مواد ڏانھن هلو

ماڊيول:Portal

کليل ڄاڻ چيڪلي، وڪيپيڊيا مان



هن ماڊيول ۾ ٻه فنڪشن آهن، portal ۽ image. portal هڪ خانو تيار ڪري ٿو جنهن ۾ پورٽل يا گهڻن پورٽلن ڏانهن ڳنڍڻا هوندا آهن، ۽ اهو {{portal}} سانچو ۾ استعمال ٿيندو آهي. اهو گهڻو ڪري ڪنهن مقالي جي "ڏسو پڻ" واري حصي ۾ ڪم آندو ويندو آهي. image فنڪشن مقرر ڪيل پورٽل لاءِ استعمال ٿيندڙ تصوير جو نالو تيار ڪري ٿو.

ٽيسٽ ڪيسن لاءِ هتي، هتي، ۽ هتي ڏسو.

پورٽل فنڪشن

[سنواريو]

پورٽل فنڪشن پورٽل ڳنڍڻن جو هڪ خانو تيار ڪري ٿو.

استعمال

[سنواريو]

بنيادي استعمال

{{#invoke:Portal|portal |ڪيناڊا 1 |ڪيناڊا 2 |ڪيناڊا 3 |... }}

مقالن جي اندر، پورٽل فنڪشن جو نڪرندڙ نتيجو مقالي جي ڏسو پڻ واري حصي جي مٿان رکڻ لاءِ ٺاهيو ويو آهي. جيڪڏهن ڏسو پڻ وارو حصو موجود نه هجي ته توهان ان کي ٻاهريان ڳنڍڻا واري حصي ۾ رکي سگهو ٿا، جيڪڏهن اتي ٻيا ٻاهريان ڳنڍڻا به موجود هجن. رڳو هن خاني لاءِ الڳ "ٻاهريان ڳنڍڻا" وارو حصو نه ٺاهيو: جيڪڏهن ٻاهريان ڳنڍڻا وارو حصو نه هجي ته مقالي جي آخر ۾ {{Portal bar}} استعمال ڪرڻ تي غور ڪريو. جيڪڏهن {{Portal bar}} استعمال ڪيو وڃي ته ان کي ڀينر رٿائن ڏانهن ڳنڍڻن سان {{Subject bar}} وسيلي گڏ ڪرڻ تي غور ڪريو.

ٻين قسمن جي صفحن تي پورٽلن جي جڳھ بابت ڪي خاص قاعدا نه آهن.

مثال

[سنواريو]

ساڄي پاسي ننڍي لکت وارو خانو گهڻن پورٽلن کي شامل ڪري سگهي ٿو.

خانو

سانچو:ڪيناڊا {{ڪيناڊا}}

سانچو:ڪيناڊا {{ڪيناڊا|مثال}}

کاٻي پاسي عام ماپ جي لکت سان لڪيروار صورت؛ پيراميٽرن جي فهرست لاءِ سانچو:Portal-inline ڏسو.


ساڄي پاسي عام ماپ جي لکت سان لڪيروار صورت: وڌيڪ معلومات لاءِ Template:Portal ڏسو. {{|border=no ڪيناڊا}}

پٽي

پٽي واري صورت عام طور گهڻن پورٽلن لاءِ استعمال ٿيندي آهي. هي سانچو "ڏسو پڻ" واري حصي ۾ نه اچڻ گهرجي. موجب هي هيٺيون مواد آهي ۽ معياري نيويگيشن سانچن کان هيٺ رکيو ويندو آهي.

{{Portal bar|ڪيناڊا|مثال|border=no}}

پيراميٽر

[سنواريو]
نالو قدر وضاحت
1, 2, 3 ... پورٽل جو نالو، مثال Literature جڳهه وارا پيراميٽر اهي پورٽل مقرر ڪن ٿا جيڪي ڏيکارڻا آهن.
left yes جيڪڏهن yes مقرر ڪيو وڃي ته پورٽل صفحي جي ساڄي پاسي بدران کاٻي پاسي ظاهر ٿيندو.
margin CSS مارجن جي قيمت، مثال 1.2em 3em 0.5em 1em ان سان توهان پنهنجي مرضي موجب مارجن مقرر ڪري سگهو ٿا. سڀ جائز CSS مارجن قيمتون قبول ڪيون وڃن ٿيون.
break yes جيڪڏهن yes مقرر ڪيو وڃي ته پورٽل جي نالي کان پوءِ ۽ لفظ portal کان اڳ هڪ سٽ ٽٽڻ شامل ڪيو ويندو.
redlinks هنن مان ڪو به قدر: yes, y, true, يا include ڳاڙها ڳنڍڻا ڏيکاريا ويندا. ڊفالٽ طور ڳاڙها ڳنڍڻا لڪايل هوندا آهن.
nominimum هنن مان ڪو به قدر: yes, y, يا true جيڪڏهن ڪو به پيراميٽر فراهم نه ڪيو ويو هجي ته خبرداري کي روڪي ٿو. هي ان وقت فائديمند ٿي سگهي ٿو جڏهن Template:Portal کي ڪو ٻيو سانچو سڏي رهيو هجي.
border هنن مان ڪو به قدر: no, n, يا false ڪنارو ۽ پسمنظر بند ڪريو
tracking هنن مان ڪو به قدر: no, n, false ٽريڪنگ زمرا بند ڪيا ويندا. ڊفالٽ طور ٽريڪنگ زمرا استعمال ٿيندا آهن، سواءِ ڪجهه مخصوص نالي جڳهن ۽ انهن صفحن جي جن جي نالن ۾ "/archive"، "/doc" يا "/test" شامل هجي.

غلطيءَ جي ٽريڪنگ

[سنواريو]

جيڪڏهن module کي غلط نموني استعمال ڪيو وڃي ته صفحو ٽريڪنگ زمري ۾ شامل ڪيو ويندو.

هيٺين مان جيڪڏهن ڪا به ڳالهه صحيح هجي ته ٽريڪنگ زمرا لاڳو نه ٿيندا:

  1. انهيءَ استعمال لاءِ ٽريڪنگ خاص طور بند ڪئي وئي هجي. اهو اختياري پيراميٽر |tracking= کي هنن مان ڪنهن به قدر تي مقرر ڪرڻ سان ڪيو ويندو آهي: no, n, false
  2. سانچو انهن نالي جڳهن مان ڪنهن هڪ ۾ استعمال ٿيو هجي: Talk, User, User talk, Wikipedia talk, File talk, Template talk, Category talk, Portal talk, Draft, Draft talk, Module talk
  3. جنهن عنوان واري صفحي تي سانچو استعمال ٿيو آهي، ان ۾ وڏن يا ننڍن اکرن جي فرق کان سواءِ هيٺين مان ڪو هڪ سلسلو شامل هجي: "/archive"، "/doc"، "/test"
مجموعا تازه ڪرڻ لاءِ صفحو صاف ڪريو

{{#ifeq: module | module ||

ڏسو پڻ

[سنواريو]
مکيه پورٽل ٺاهڻ وارا سانچا
  • {{Box portal skeleton}} - پورٽل جا مکيه صفحا ٺاهڻ لاءِ استعمال ٿيندو آهي۔
  • {{Random portal component}} - پورٽل جي مکيه صفحي تي استعمال ٿيندو آهي ته جيئن پورٽل جي ذيلي صفحن مان مضمون بي ترتيب (random) نموني ڏيکاريا وڃن۔
  • {{Random portal component with nominate}} - پورٽل جي مکيه صفحي تي ذيلي صفحن مان مضمون بي ترتيب ڏيکارڻ لاءِ استعمال ٿيندو آهي، ۽ ان سان گڏ ٻين نمايان foo مضمونن کي نامزد ڪرڻ جو اختيار پڻ مهيا ڪندو آهي۔
  • {{Random subpage}} - پورٽل جي مکيه صفحي تي ذيلي صفحن مان مضمون بي ترتيب نموني ڏيکارڻ لاءِ استعمال ٿيندو آهي۔ هي سانچو خاص طور تي پورٽل جي مکيه صفحي تي ڇا توهان ڄاڻو ٿا... جهڙا حصا ٺاهڻ لاءِ مناسب آهي، جتي ڪيترائي ڇا توهان ڄاڻو ٿا... حقيقتون شامل ڪيون وڃن۔
  • {{ Portal subpage}} - هڪ دٻو (box) ڏيکارڻ لاءِ استعمال ٿيندو آهي جنهن ۾ ذيلي صفحي ڏانهن ڳنڍ (link) شامل هوندي آهي۔
  • {{Numbered subpages}} - پورٽل جي ذيلي صفحن تي 50 ڳنڍن سان مضمونن جا لنڪ ٺاهڻ لاءِ استعمال ٿيندو آهي۔
  • {{Random box-header subpage}} - نمبر ڏنل ذيلي صفحي کي ٽرانسڪليوڊ ڪرڻ (transclude) لاءِ استعمال ٿيندو آهي۔
مکيه پورٽل صفحي جي ترتيب ڏيڻ وارا سانچا
3
اهي سانچا ڳنڍن کي ترتيب ڏيڻ لاءِ استعمال ٿيندا آهن
3
هي سانچا ذيلي صفحن تي مضمونن کي ترتيب ڏيڻ لاءِ استعمال ٿيندا آهن

{{Selected X}} - اهڙين حالتن لاءِ عام سانچو جيڪي هتي هيٺ درج نه آهن۔

3
منسلڪ سانچا

استعمال

[سنواريو]

سانچو:ڪيناڊا

بنيادي استعمال

{{Portal |ڪيناڊا 1 |ڪيناڊا 2 |ڪيناڊا 3 |... }}

مقالن جي اندر، هي سانچو مقالي جي ڏسو پڻ واري حصي جي مٿان رکڻ لاءِ ٺاهيو ويو آهي. جيڪڏهن ڏسو پڻ وارو حصو موجود نه هجي ته توهان ان کي ٻاهريان ڳنڍڻا واري حصي ۾ رکي سگهو ٿا، جيڪڏهن اتي ٻيا ٻاهريان ڳنڍڻا به موجود هجن. رڳو هن خاني لاءِ الڳ "ٻاهريان ڳنڍڻا" وارو حصو نه ٺاهيو: جيڪڏهن ٻاهريان ڳنڍڻا وارو حصو نه هجي ته مقالي جي آخر ۾ {{Portal bar}} استعمال ڪرڻ تي غور ڪريو. جيڪڏهن {{Portal bar}} استعمال ڪيو وڃي ته ان کي ڀينر رٿائن ڏانهن ڳنڍڻن سان {{Subject bar}} وسيلي گڏ ڪرڻ تي غور ڪريو.

ٻين قسمن جي صفحن تي پورٽلن جي جڳھ بابت ڪي خاص قاعدا نه آهن.

تصوير

[سنواريو]

پورٽل تصويرن جا نالا Module:Portal/images جي ذيلي صفحن ۾ محفوظ هوندا آهن، جيڪي پورٽل نالي جي پهرئين اکر موجب ترتيب ڏنل هوندا آهن. مثال طور Portal:Feminism جو پهريون اکر "F" آهي، تنهنڪري ان جي تصوير جو نالو Module:Portal/images/f تي محفوظ آهي. جيڪڏهن صحيح صفحي تي ڪنهن پورٽل لاءِ داخلا موجود هجي ته ساڳي تصوير پورٽل ڳنڍڻي جي ڀرسان ڏيکاري ويندي. جيڪڏهن ڪا تصوير نه ملي ته File:Portal-puzzle.svg بدران ڏيکاري ويندي.

پورٽل تصويرن لاءِ عرفي نالا پڻ مقرر ڪري سگهجن ٿا. مثال طور ڪوڊ {{Portal|Detroit}} ساڳي تصوير پيدا ڪندو جيڪا ڪوڊ {{Portal|Metro Detroit}} ڪندو آهي. "Detroit" وارو عرف Module:Portal/images/aliases صفحي تي موجود آهي.

تصوير معلوم ڪرڻ وارو الگورٿم وڏن ۽ ننڍن اکرن کي الڳ نٿو ڪري. مثال طور ڪوڊ {{Portal|Detroit}} ساڳي تصوير پيدا ڪندو جيڪا ڪوڊ {{Portal|detroit}} ڪندو (جيتوڻيڪ پورٽل ڳنڍڻا مختلف هوندا). پورٽل نالا تصويرن وارن ذيلي صفحن ۾ ننڍن اکرن ۾ محفوظ ڪيا ويندا آهن، ۽ داخل ڪيل نالو چڪاس کان اڳ ننڍن اکرن ۾ تبديل ڪيو ويندو آهي.

فهرست ۾ نيون تصويرون شامل ڪرڻ لاءِ مهرباني ڪري Template talk:Portal تي محفوظ ترميم جي درخواست ڏيو ته جيئن ڪو منتظم توهان لاءِ صحيح ذيلي صفحي ۾ ترميم ڪري سگهي. پورٽل تصويرون يا ته عوامي ملڪيت ۾ هجڻ گهرجن يا آزاد اجازتنامي هيٺ دستياب هجڻ گهرجن، جيڪو تجارتي ٻيهر استعمال ۽ اخذ ڪيل ڪم جي اجازت ڏئي؛ غير آزاد / فيئر-يوز تصويرون قبول نه آهن. {{Portal icon demonstration}} سانچو اهو فيصلو ڪرڻ ۾ مددگار ٿي سگهي ٿو ته ڪا تصوير پورٽل آئڪن طور مناسب آهي يا نه؛ اهو تصوير کي انهيءَ ئي ماپ ۽ انداز ۾ ڏيکاري ٿو جيڪو {{Portal}} سانچو ڊفالٽ طور استعمال ڪري ٿو.

انهن پورٽلن ۽ انهن جي عرفن جي فهرست جن وٽ آئڪن موجود نه آهي، Category:Portal templates with default image ۾ ملي سگهي ٿي.

مثال

[سنواريو]

ساڄي پاسي ننڍي لکت وارو خانو گهڻن پورٽلن کي شامل ڪري سگهي ٿو.

خانو

سانچو:ڪيناڊا {{ڪيناڊا}}

سانچو:ڪيناڊا {{ڪيناڊا|مثال}}

کاٻي پاسي عام ماپ جي لکت سان لڪيروار صورت؛ وڌيڪ پيراميٽرن جي فهرست لاءِ سانچو:Portal-inline ڏسو.

لڪيروار

ساڄي پاسي عام ماپ جي لکت سان لڪيروار صورت: وڌيڪ معلومات لاءِ سانچو:Portal ڏسو.

پٽي

پٽي واري صورت عام طور گهڻن پورٽلن لاءِ استعمال ٿيندي آهي. هي سانچو "ڏسو پڻ" واري حصي ۾ نه اچڻ گهرجي. موجب هي هيٺيون مواد آهي ۽ معياري نيويگيشن سانچن کان هيٺ رکيو ويندو آهي.

{{Portal bar|ڪيناڊا|مثال|border=no}}

پيراميٽر

[سنواريو]
نالو قدر وضاحت
1, 2, 3 ... پورٽل جو نالو، مثال Literature جڳهه وارا پيراميٽر اهي پورٽل مقرر ڪن ٿا جيڪي ڏيکارڻا آهن.
left yes جيڪڏهن yes مقرر ڪيو وڃي ته پورٽل صفحي جي ساڄي پاسي بدران کاٻي پاسي ظاهر ٿيندو.
margin CSS مارجن جي قيمت، مثال 1.2em 3em 0.5em 1em ان سان توهان پنهنجي مرضي موجب مارجن مقرر ڪري سگهو ٿا. سڀ جائز CSS مارجن قيمتون قبول ڪيون وڃن ٿيون.
break yes جيڪڏهن yes مقرر ڪيو وڃي ته پورٽل جي نالي کان پوءِ ۽ لفظ portal کان اڳ هڪ سٽ ٽٽڻ شامل ڪيو ويندو.
redlinks هنن مان ڪو به قدر: yes, y, true, يا include ڳاڙها ڳنڍڻا ڏيکاريا ويندا. ڊفالٽ طور ڳاڙها ڳنڍڻا لڪايل هوندا آهن.
nominimum هنن مان ڪو به قدر: yes, y, يا true جيڪڏهن ڪو به پيراميٽر فراهم نه ڪيو ويو هجي ته خبرداري کي روڪي ٿو. هي ان وقت فائديمند ٿي سگهي ٿو جڏهن Template:Portal کي ڪو ٻيو سانچو سڏي رهيو هجي.
border هنن مان ڪو به قدر: no, n, يا false ڪنارو ۽ پسمنظر بند ڪريو.
tracking هنن مان ڪو به قدر: no, n, false ٽريڪنگ زمرا بند ڪيا ويندا. ڊفالٽ طور ٽريڪنگ زمرا استعمال ٿيندا آهن، سواءِ ڪجهه مخصوص نالي جڳهن ۽ انهن صفحن جي جن جي نالن ۾ "/archive"، "/doc" يا "/test" شامل هجي.

غلطيءَ جي ٽريڪنگ

[سنواريو]

جيڪڏهن template کي غلط نموني استعمال ڪيو وڃي ته صفحو ٽريڪنگ زمري ۾ شامل ڪيو ويندو.

هيٺين مان جيڪڏهن ڪا به ڳالهه صحيح هجي ته ٽريڪنگ زمرا لاڳو نه ٿيندا:

  1. انهيءَ استعمال لاءِ ٽريڪنگ خاص طور بند ڪئي وئي هجي. اهو اختياري پيراميٽر |tracking= کي هنن مان ڪنهن به قدر تي مقرر ڪرڻ سان ڪيو ويندو آهي: no, n, false
  2. سانچو انهن نالي جڳهن مان ڪنهن هڪ ۾ استعمال ٿيو هجي: Talk, User, User talk, Wikipedia talk, File talk, Template talk, Category talk, Portal talk, Draft, Draft talk, Module talk
  3. جنهن عنوان واري صفحي تي سانچو استعمال ٿيو آهي، ان ۾ وڏن يا ننڍن اکرن جي فرق کان سواءِ هيٺين مان ڪو هڪ سلسلو شامل هجي: "/archive"، "/doc"، "/test"
مجموعا تازه ڪرڻ لاءِ صفحو صاف ڪريو

{{#ifeq: | module ||

ڏسو پڻ

[سنواريو]
مکيه پورٽل ٺاهڻ وارا سانچا
  • {{Box portal skeleton}} - پورٽل جا مکيه صفحا ٺاهڻ لاءِ استعمال ٿيندو آهي۔
  • {{Random portal component}} - پورٽل جي مکيه صفحي تي استعمال ٿيندو آهي ته جيئن پورٽل جي ذيلي صفحن مان مضمون بي ترتيب (random) نموني ڏيکاريا وڃن۔
  • {{Random portal component with nominate}} - پورٽل جي مکيه صفحي تي ذيلي صفحن مان مضمون بي ترتيب ڏيکارڻ لاءِ استعمال ٿيندو آهي، ۽ ان سان گڏ ٻين نمايان foo مضمونن کي نامزد ڪرڻ جو اختيار پڻ مهيا ڪندو آهي۔
  • {{Random subpage}} - پورٽل جي مکيه صفحي تي ذيلي صفحن مان مضمون بي ترتيب نموني ڏيکارڻ لاءِ استعمال ٿيندو آهي۔ هي سانچو خاص طور تي پورٽل جي مکيه صفحي تي ڇا توهان ڄاڻو ٿا... جهڙا حصا ٺاهڻ لاءِ مناسب آهي، جتي ڪيترائي ڇا توهان ڄاڻو ٿا... حقيقتون شامل ڪيون وڃن۔
  • {{ Portal subpage}} - هڪ دٻو (box) ڏيکارڻ لاءِ استعمال ٿيندو آهي جنهن ۾ ذيلي صفحي ڏانهن ڳنڍ (link) شامل هوندي آهي۔
  • {{Numbered subpages}} - پورٽل جي ذيلي صفحن تي 50 ڳنڍن سان مضمونن جا لنڪ ٺاهڻ لاءِ استعمال ٿيندو آهي۔
  • {{Random box-header subpage}} - نمبر ڏنل ذيلي صفحي کي ٽرانسڪليوڊ ڪرڻ (transclude) لاءِ استعمال ٿيندو آهي۔
مکيه پورٽل صفحي جي ترتيب ڏيڻ وارا سانچا
3
اهي سانچا ڳنڍن کي ترتيب ڏيڻ لاءِ استعمال ٿيندا آهن
3
هي سانچا ذيلي صفحن تي مضمونن کي ترتيب ڏيڻ لاءِ استعمال ٿيندا آهن

{{Selected X}} - اهڙين حالتن لاءِ عام سانچو جيڪي هتي هيٺ درج نه آهن۔

3
منسلڪ سانچا

--[==[ This module is a Lua implementation of the old {{Portal}} template. As of August 2015 it is used on nearly 42598 articles.
-- Please take care when updating it! It outputs two functions: p.portal, which generates a table of portals, and p.image, which
-- produces the image name for an individual portal.

-- The portal image data is kept in submodules of [[Module:Portal/images]], listed below:
-- [[Module:Portal/images/ا]]		- for portal names beginning with "ا".
-- [[Module:Portal/images/ب]]		- for portal names beginning with "ب".
-- [[Module:Portal/images/ث]]		- for portal names beginning with "ث".
-- [[Module:Portal/images/ڈ]]		- for portal names beginning with "ڈ".
-- [[Module:Portal/images/خ]]		- for portal names beginning with "خ".
-- [[Module:Portal/images/ن]]		- for portal names beginning with "ف".
-- [[Module:Portal/images/ج]]		- for portal names beginning with "G".
-- [[Module:Portal/images/h]]		- for portal names beginning with "H".
-- [[Module:Portal/images/i]]		- for portal names beginning with "I".
-- [[Module:Portal/images/چ]]		- for portal names beginning with "چ".
-- [[Module:Portal/images/ک]]		- for portal names beginning with "ک".
-- [[Module:Portal/images/ل]]		- for portal names beginning with "ل".
-- [[Module:Portal/images/م]]		- for portal names beginning with "م".
-- [[Module:Portal/images/ن]]		- for portal names beginning with "ن".
-- [[Module:Portal/images/o]]		- for portal names beginning with "O".
-- [[Module:Portal/images/پ]]		- for portal names beginning with "پ".
-- [[Module:Portal/images/ق]]		- for portal names beginning with "ق".
-- [[Module:Portal/images/ر]]		- for portal names beginning with "ر".
-- [[Module:Portal/images/س]]		- for portal names beginning with "س".
-- [[Module:Portal/images/t]]		- for portal names beginning with "T".
-- [[Module:Portal/images/u]]		- for portal names beginning with "U".
-- [[Module:Portal/images/v]]		- for portal names beginning with "V".
-- [[Module:Portal/images/و]]		- for portal names beginning with "و".
-- [[Module:Portal/images/x]]		- for portal names beginning with "X".
-- [[Module:Portal/images/y]]		- for portal names beginning with "Y".
-- [[Module:Portal/images/ز]]		- for portal names beginning with "ز".
-- [[Module:Portal/images/دیگر]]	- for portal names beginning with any other letters. This includes numbers,
-- 									  letters with diacritics, and letters in non-Latin alphabets.
-- [[Module:Portal/images/aliases]]	- for adding aliases for existing portal names. Use this page for variations
-- 									  in spelling and diacritics, etc., no matter what letter the portal begins with.
--
-- The images data pages are separated by the first letter to reduce server load when images are added, changed, or removed.
-- Previously all the images were on one data page at [[Module:Portal/images]], but this had the disadvantage that all
-- 5,000,000 pages using this module needed to be refreshed every time an image was added or removed.
]==]
local p = {}

-- determine whether we're being called from a sandbox
local isSandbox = mw.getCurrentFrame():getTitle():find('sandbox', 1, true)
local sandbox = isSandbox and '/sandbox' or ''

local function sandboxVersion(s)
	return isSandbox and s .. '-sand' or s
end

local templatestyles = 'Module:Portal' .. sandbox .. '/styles.css'

local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')

-- Namespace IDs safer than localized names
local BAD_NAMESPACES = {
	[2] = true,   -- User
	[4] = true,   -- Wikipedia/Project
	[10] = true,  -- Template
	[118] = true  -- Draft
}

-- Portal namespace ID in MediaWiki
local PORTAL_NAMESPACE = 100
local PORTAL_NAME = mw.site.namespaces[PORTAL_NAMESPACE] and mw.site.namespaces[PORTAL_NAMESPACE].name or 'Portal'
local PORTAL_DISPLAY = 'باب'

-- Check whether to do tracking in this namespace
-- Returns true unless the page is one of the banned namespaces
local function checkTracking(title)
	local thisPage = title or mw.title.getCurrentTitle()
	if thisPage.isTalkPage then
		return false
	end
	if BAD_NAMESPACES[thisPage.namespace] then
		return false
	end
	return true
end

local function matchImagePage(s)
	-- Finds the appropriate image subpage given a lower-case
	-- portal name plus the first letter of that portal name.
	if type(s) ~= 'string' or #s < 1 then
		return
	end

	local firstLetter = mw.ustring.sub(s, 1, 1)
	local imagePage

	if mw.ustring.find(firstLetter, '^[a-z]') then
		imagePage = 'Module:Portal/images/' .. firstLetter .. sandbox
	else
		imagePage = 'Module:Portal/images/other' .. sandbox
	end

	return mw.loadData(imagePage)[s]
end

local function getAlias(s)
	-- Gets an alias from the image alias data page.
	local aliasData = mw.loadData('Module:Portal/images/aliases' .. sandbox)
	for portal, aliases in pairs(aliasData) do
		for _, alias in ipairs(aliases) do
			if alias == s then
				return portal
			end
		end
	end
end

local defaultImage = 'Portal-puzzle.svg|link=|alt=' .. PORTAL_DISPLAY

local function getImageName(s)
	-- Gets the image name for a given string.
	if type(s) ~= 'string' or #s < 1 then
		return defaultImage
	end

	s = mw.ustring.lower(s)
	local image = matchImagePage(s) or matchImagePage(getAlias(s)) or defaultImage
	image = mw.ustring.gsub(image, '^File:', '')
	image = mw.ustring.gsub(image, '^Image:', '')
	return image
end

local function exists(title)
	local success, pageExists = pcall(function()
		return title.exists
	end)
	-- If success = false, then we're out of expensive parser function calls and can't check whether it exists
	-- in that case, don't throw a Lua error
	return not success or pageExists
end

-- Function to check argument portals for errors, generate tracking categories if needed
-- Arguments:
--   portals: raw list of portals
--   args.tracking: is tracking requested? (will not track on bad titles or namespaces)
--   args.redlinks: should redlinks be displayed?
--   args.minPortals: minimum number of portal arguments
--   args.maxPortals: maximum number of portal arguments
-- Returns:
--   portals = list of portals, with redlinks purged (if args.redlinks=false)
--   trackingCat = possible tracking category
--   errorMsg = error message
function p._checkPortals(portals, args)
	local trackingCat = ''
	local errMsg = nil

	-- Tracking is on by default.
	-- It is disabled if any of the following is true
	-- 1/ the parameter "tracking" is set to 'no', 'n', or 'false'
	-- 2/ the current page fails the namespace or pagename tests
	local trackingEnabled = args.tracking and checkTracking()

	args.minPortals = args.minPortals or 1
	args.maxPortals = args.maxPortals or -1

	-- check for too few portals
	if #portals < args.minPortals then
		errMsg = 'please specify at least ' .. args.minPortals .. ' portal' .. (args.minPortals > 1 and 's' or '')
		trackingCat = trackingEnabled and '[[Category:Portal templates with too few portals]]' or ''
		return portals, trackingCat, errMsg
	end

	-- check for too many portals
	if args.maxPortals >= 0 and #portals > args.maxPortals then
		errMsg = 'too many portals (maximum = ' .. args.maxPortals .. ')'
		trackingCat = trackingEnabled and '[[Category:Portal templates with too many portals]]' or ''
		return portals, trackingCat, errMsg
	end

	if not args.redlinks or trackingEnabled then
		-- make new list of portals that exist
		local existingPortals = {}
		for _, portal in ipairs(portals) do
			local portalTitle = mw.title.new(portal, PORTAL_NAMESPACE)

			-- if portal exists, put it into list
			if portalTitle and exists(portalTitle) then
				table.insert(existingPortals, portal)
			-- otherwise set tracking cat
			elseif trackingEnabled then
				trackingCat = '[[Category:Portal templates with redlinked portals]]'
			end
		end

		-- If redlinks is off, use portal list purged of redlinks
		portals = args.redlinks and portals or existingPortals

		-- if nothing left after purge, set tracking cat
		if #portals == 0 and trackingEnabled then
			trackingCat = trackingCat .. '[[Category:Pages with empty portal template]]'
		end
	end

	return portals, trackingCat, errMsg
end

local function portalBox(args)
	return mw.html.create('ul')
		:attr('role', 'navigation')
		:attr('aria-label', PORTAL_DISPLAY)
		:addClass('noprint')
		:addClass(args.error and '' or sandboxVersion('portalbox'))
		:addClass(args.border and sandboxVersion('portalborder') or '')
		:addClass(sandboxVersion(args.left and 'portalleft' or 'portalright'))
		:css('margin', args.margin or nil)
		:newline()
end

local function fillBox(root, contents)
	for _, item in ipairs(contents) do
		local entry = root:tag('li')
		entry:addClass(sandboxVersion('portalbox-entry'))

		local image = entry:tag('span')
		image:addClass(sandboxVersion('portalbox-image'))
		image:wikitext(item[1])

		local link = entry:tag('span')
		link:addClass(sandboxVersion('portalbox-link'))
		link:wikitext(item[2])
	end
	return root
end

local function noviewer(portalImage)
	-- Function to add noviewer class to filespec for portalImage
	local newImage, hasClass = mw.ustring.gsub(portalImage, 'class%s*=[^%|]+', '%0 noviewer')
	if hasClass == 0 then
		newImage = newImage .. '|class=noviewer'
	end
	return newImage
end

function p._portal(portals, args)
	-- This function builds the portal box used by the {{portal}} template.

	-- Normalize all arguments
	if args.redlinks == 'include' then
		args.redlinks = true
	end
	args.addBreak = args['break']

	for key, default in pairs({
		left = false,
		tracking = true,
		nominimum = false,
		redlinks = false,
		addBreak = false,
		border = true
	}) do
		if args[key] == nil then
			args[key] = default
		end
		args[key] = yesno(args[key], default)
	end

	local root = portalBox(args)

	local trackingCat = ''
	local errMsg = nil
	args.minPortals = args.nominimum and 0 or 1
	args.maxPortals = -1

	portals, trackingCat, errMsg = p._checkPortals(portals, args)
	root:wikitext(trackingCat)

	-- if error message, put it in the box and return
	if errMsg then
		if args.border then -- suppress error message when border=no
			args.error = true -- recreate box without fancy formatting
			root = portalBox(args)
			root:wikitext(trackingCat)
			local errTag = root:tag('strong')
			errTag:addClass('error')
			errTag:css('padding', '0.2em')
			errTag:wikitext('Error: ' .. errMsg)
		end
		return tostring(root)
	end

	-- if no portals (and no error), just return tracking category
	if #portals == 0 then
		return trackingCat
	end

	local contents = {}
	local defaultUsed = nil

	-- Display the portals specified in the positional arguments.
	for _, portal in ipairs(portals) do
		local portalImage = getImageName(portal)

		if portalImage == defaultImage then
			defaultUsed = portal
		else
			portalImage = noviewer(portalImage)
		end

		local image = string.format('[[File:%s|32x28px]]', portalImage)
		local link = string.format(
			'[[%s:%s|%s%s%s]]',
			PORTAL_NAME,
			portal,
			portal,
			args.addBreak and '<br />' or ' ',
			PORTAL_DISPLAY
		)

		table.insert(contents, {image, link})
	end

	if defaultUsed and args.tracking and checkTracking() then
		local cat = string.format('[[Category:Portal templates with default image|%s]]', defaultUsed)
		root:wikitext(cat)
	end

	return tostring(fillBox(root, contents))
end

function p._demo(imageList, args)
	for key, default in pairs({left = false, border = true}) do
		if args[key] == nil then
			args[key] = default
		end
		args[key] = yesno(args[key], default)
	end

	local root = portalBox(args)
	local contents = {}

	-- Display the portals specified in the positional arguments.
	for _, fn in ipairs(imageList) do
		local image = string.format('[[File:%s|32x28px]]', noviewer(fn))
		local link = string.format('[[:File:%s|%s]]', fn, fn)
		table.insert(contents, {image, link})
	end

	return tostring(fillBox(root, contents))
end

function p._image(portal, keep)
	-- Wrapper function to allow getImageName() to be accessed through #invoke.
	-- backward compatibility: if table passed, take first element
	if type(portal) == 'table' then
		portal = portal[1]
	end

	local name = getImageName(portal)

	-- If keep is yes (or equivalent), then allow all metadata (like image borders) to be returned
	-- also, add "noviewer" class to metadata
	local keepargs = yesno(keep)
	if keepargs then
		return noviewer(name)
	end

	-- otherwise, just keep filename, plus optional category
	local args = mw.text.split(name, '|', true)
	local result = {args[1]}

	-- parse name, looking for category arguments
	for i = 2, #args do
		local m = mw.ustring.match(args[i], '^%s*category%s*=')
		if m then
			table.insert(result, args[i])
		end
	end

	-- reassemble arguments
	return table.concat(result, '|')
end

local function getAllImageTable()
	-- Returns an array containing all image subpages (minus aliases) as loaded by mw.loadData.
	local images = {}
	for _, subpage in ipairs{
		'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
		'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'other'
	} do
		local imageTable = mw.loadData('Module:Portal/images/' .. subpage .. sandbox)
		for portal, image in pairs(imageTable) do
			local parts = mw.text.split(image, '|')
			images[portal] = parts[1]
		end
	end
	return images
end

function p._displayAll(portals, args)
	-- This function displays all portals that have portal images. This function is for maintenance purposes and should not be used in
	-- articles, for two reasons: 1) there are over 1500 portals with portal images, and 2) the module doesn't record how the portal
	-- names are capitalized, so the portal links may be broken.
	local lang = mw.language.getContentLanguage()
	portals = portals or {}

	for portal in pairs(getAllImageTable()) do
		table.insert(portals, lang:ucfirst(portal))
	end

	table.sort(portals)
	args.redlinks = args.redlinks or 'yes'
	return p._portal(portals, args)
end

function p._imageDupes()
	-- This function searches the image subpages to find duplicate images.
	local existing, dupes = {}, {}

	for portal, image in pairs(getAllImageTable()) do
		if not existing[image] then
			existing[image] = portal
		else
			table.insert(
				dupes,
				string.format(
					'The image "[[:File:%s|%s]]" is used for both portals "%s" and "%s".',
					image, image, existing[image], portal
				)
			)
		end
	end

	if #dupes < 1 then
		return 'No duplicate images found.'
	else
		return 'The following duplicate images were found:\n* ' .. table.concat(dupes, '\n* ')
	end
end

local function processPortalArgs(args)
	-- This function processes a table of arguments and returns two tables:
	-- (1) an array of portal names for processing by ipairs
	-- (2) a table of named arguments that specify style options, etc.
	args = type(args) == 'table' and args or {}

	local portals = {}
	local namedArgs = {}

	for k, v in pairs(args) do
		if type(k) == 'number' and type(v) == 'string' then
			table.insert(portals, k)
		elseif type(k) ~= 'number' then
			namedArgs[k] = v
		end
	end

	table.sort(portals)

	for i, v in ipairs(portals) do
		portals[i] = args[v]
	end

	return portals, namedArgs
end

-- Entry point for sorting portals from other named arguments
function p._processPortalArgs(args)
	return processPortalArgs(args)
end

function p.image(frame)
	local origArgs = getArgs(frame)
	local portals, args = processPortalArgs(origArgs)
	return p._image(portals[1], origArgs[2] or args.keep)
end

function p.demo(frame)
	local args = getArgs(frame)
	local styles = frame:extensionTag{
		name = 'templatestyles',
		args = {src = templatestyles}
	}
	return styles .. p._demo(args, args)
end

local function makeWrapper(funcName)
	-- Processes external arguments and sends them to the other functions.
	return function(frame)
		local origArgs = getArgs(frame)
		local portals, args = processPortalArgs(origArgs)

		local results = ''
		if funcName == '_portal' or funcName == '_displayAll' then
			results = frame:extensionTag{
				name = 'templatestyles',
				args = {src = templatestyles}
			}
		end

		return results .. p[funcName](portals, args)
	end
end

for _, funcName in ipairs{'portal', 'imageDupes', 'displayAll'} do
	p[funcName] = makeWrapper('_' .. funcName)
end

return p