Manual:MediaWiki architecture/ar

منذ البداية، تم تطوير ميدياويكي خصيصًا ليكون برنامج ويكيبيديا. لقد عمل المطورون على تسهيل إعادة الاستخدام من قبل مستخدمي الطرف الثالث، لكن تأثير ويكيبيديا وتحيزها ساهم في تشكيل بنية ميدياويكي عبر تاريخها.

تعد ويكيبيديا واحدة من أفضل عشرة مواقع إلكترونية في العالم، حيث تستقبل حاليًا حوالي 400 مليون زائر فريد شهريًا. تحصل على أكثر من 100.000 نقرة في الثانية. ويكيبيديا غير مدعومة تجاريًا بالإعلانات؛ يتم دعمه بالكامل من قبل منظمة غير ربحية، وهي مؤسسة ويكيميديا، والتي تعتمد على التبرعات كنموذج تمويل أساسي لها. وهذا يعني أن ميدياويكي لا يجب أن تدير موقعًا من أفضل عشرة مواقع فحسب، بل يجب أن تفعل ذلك أيضًا بميزانية صغيرة. لتلبية هذه المطالب، تمتلك ميديا ويكي تحيزًا كبيرًا نحو الأداء والخزن الآلي والتحسين. يتم إعادة تشغيل الميزات الثمينة التي لا يمكن تمكينها في ويكيبيديا أو تعطيلها من خلال متغير التكوين؛ هناك توازن لا نهاية له بين الأداء والميزات.

لا يقتصر تأثير ويكيبيديا على بنية ميدياويكي على الأداء. على عكس أنظمة إدارة المحتوى العامة، تمت كتابة ميدياويكي في الأصل لغرض محدد للغاية: دعم المجتمع الذي يقوم بإنشاء وتنظيم المعرفة القابلة لإعادة الاستخدام بحرية على منصة مفتوحة. هذا يعني، على سبيل المثال، أن ميديا ويكي لا تشمل الميزات العادية الموجودة في CMSs الشركات (مثل سير العمل السهل للنشر أو ACLs) ، ولكن تقدم مجموعة متنوعة من الأدوات للتعامل مع الرسائل غير المرغوب فيها والفوضى.

لذا، منذ البداية، أثر احتياجات وفعال مجتمع متطور باستمرار من مشاركين ويكيبيديا على تطوير مديا ويكي، وعكس ذلك. لقد كانت بنية ميدياويكي مدفوعة عدة مرات بمبادرات بدأها أو طلبها المجتمع، مثل إنشاء ويكيميديا ​​كومنز، أو ميزة المراجعات ذات العلامات. قام المطورون بتغييرات معمارية كبيرة، مثل معالج ميدياويكي 1.12 المسبق، لأن الطريقة التي استخدم بها ميدياويكي من قبل ويكيبيدييين جعلها ضرورية.

اكتسب ميدياويكي أيضًا قاعدة مستخدمين خارجية قوية من خلال كونه برنامجًا مفتوح المصدر منذ البداية. يعلم المستخدمون الخارجيون أنه طالما أن موقع ويب رفيع المستوى مثل ويكيبيديا يستخدم ميدياويكي، فسيتم صيانة البرنامج وتحسينه. كانت ميديا ويكي تركز حقا على مواقع ويكيميديا، ولكن تم بذل جهود لجعلها أكثر عمومية وتلبية احتياجات هؤلاء المستخدمين من الطرف الثالث بشكل أفضل. على سبيل المثال، يُستخدم ميديا ويكي مع مرسومة تحميل على شبكة الإنترنت ممتازة، مما يجعل عملية التثبيت أقل ألمًا بكثير من عندما كان يتعين القيام بكل شيء عبر خط الأوامر، ويحتوي البرنامج على مسارات مُشفرة صلبة لويكيبيديا.

ومع ذلك، يظل ميدياويكي برنامج ويكيبيديا، وهذا يظهر عبر تاريخه وهندسته المعمارية.



PHP
تم اختيار PHP كإطار عمل لبرنامج "المرحلة الثانية" في ويكيبيديا في عام 2001؛ لقد تطور برنامج ميدياويكي بشكل عضوي منذ ذلك الحين، ولا يزال يتطور. معظم مطوري ميديا ويكي متطوعون يساهمون في وقتهم الفراغي، وكان عدد قليل جدا في السنوات الأولى. قد تبدو بعض قرارات تصميم البرمجيات أو الإغفالات خاطئة عند الرجوع إلى الماضي، ولكن من الصعب انتقاد المؤسسين لعدم تنفيذ بعض التجريدات التي ثبت الآن أنها بالغة الأهمية، عندما كانت قاعدة التعليمات البرمجية الأولية صغيرة جدًا، والوقت المستغرق لتطويرها قصير جدًا.

على سبيل المثال، تستخدم ميديا ويكي أسماء الفصول غير المحددة، والتي يمكن أن تسبب الصراعات عندما يضيف مطوري PHP core و PECL فصول جديدة. ونتيجة لذلك، كان يجب إعادة تسمية فئة MediaWiki  إلى   لتتوافق مع PHP 5.3. إن استخدام البادئة باستمرار لجميع الفئات (على سبيل المثال " ") كان من شأنه أن يسهل تضمين ميدياويكي داخل تطبيق أو مكتبة أخرى.

لا يُمكن أن يكون الاعتماد على PHP أفضل خيار للأداء، لأنه لم يستفيد من التحسينات التي شهدتها بعض اللغات الديناميكية الأخرى. كان استخدام جاوا سيكون أفضل بكثير للأداء، وتبسيط تنفيذ مقياس للمهام الصيانة الخلفية. من ناحية أخرى، PHP تحظى بشعبية كبيرة، مما يسهل توظيف مطورين جدد.

حتى لو كانت مديا ويكي لا تزال تحتوي على رمز "شنيع" ، تم إحداث تحسينات كبيرة على مر السنين ، وتم تقديم عناصر معمارية جديدة إلى مديا ويكي طوال تاريخها. وتشمل هذه الفئات فئة 1، 2، و 3، فئة 4 و 5، فئة 6 و 7 بدأت ميديا ويكي بدون أي من هذه الأشياء، ولكنها تدعم جميعها الميزات التي كانت موجودة منذ البداية. يهتم العديد من المطورين في المقام الأول بتطوير الميزات، وغالبًا ما يتم تجاهل الهندسة المعمارية، ثم اللحاق بها لاحقًا، حيث تصبح تكلفة العمل ضمن بنية غير كافية واضحة.

الأمن
نظرًا لأن ميدياويكي هي منصة للمواقع رفيعة المستوى مثل ويكيبيديا، فقد قام المطورون الأساسيون ومراجعو التعليمات البرمجية بفرض قواعد أمنية صارمة. لتسهيل كتابة تعليمات برمجية آمنة، يوفر ميديا ويكي للمطورين أغلفة حول مخرجات HTML واستعلامات قاعدة البيانات للتعامل مع الهروب. لتنظيف مدخلات المستخدم، يستخدم أحد فئة ، التي تحلل البيانات التي تم تمريرها في عنوان URL أو عبر نموذج POSTed. إنه يزيل "مقاطع الاقتباس السحري" ، ويزيل أحرف الإدخال غير المشروعة ويطبق تسلسلات يونيكود. يتم تجنب مزيف طلب عبر الموقع (CSRF) باستخدام الرموز ، والكتابة عبر الموقع ، من خلال التحقق من المدخلات والخروجات الخارجة ، عادةً مع وظيفة PHP $ 1. توفر ميديا ويكي أيضًا (و تستخدم) مضغوطة HTML مع فئة  ، و وظائف قاعدة البيانات التي تمنع حقن SQL.

تكوين
تقدم ميديا ويكي مئات إعدادات التكوين، المخزنة في المتغيرات العالمية في PHP. قيمتها الافتراضية محددة في $ 1، ويمكن للمدير النظام التغلب عليها عن طريق تحرير $ 2.

اعتادت ميدياويكي على الاعتماد على المتغيرات العالمية بشكل كبير ، بما في ذلك لتكوين ومعالجة السياق. يسبب الجوالات آثار أمنية خطيرة مع وظيفة PHP  (التي لم تكن ميديا ويكي بحاجة إليها منذ الإصدار 1.2). هذا النظام يحد أيضا من الاستخراجات المحتملة للتكوين، ويجعل من الصعب تحسين عملية البدء. علاوة على ذلك، تتم مشاركة مساحة اسم التكوين مع المتغيرات المستخدمة للتسجيل وسياق الكائن، مما يؤدي إلى تعارضات محتملة. من وجهة نظر المستخدم، جعلت متغيرات التكوين العالمية أيضًا مديا ويكي صعبة التكوين والحفاظ عليها. لقد كان تطوير ميدياويكي عبارة عن قصة نقل السياق ببطء من المتغيرات العالمية إلى الكائنات. يسمح تخزين سياق المعالجة في متغيرات أعضاء الكائن بإعادة استخدام هذه الكائنات بطريقة أكثر مرونة.



قاعدة بيانات وتخزين النص


كانت ميديا ويكي تستخدم قاعدة بيانات إعلامية متراجعة منذ البرمجيات المرحلة الثانية. نظام إدارة قواعد البيانات الافتراضي (والأفضل دعمًا) لـ ميدياويكي هو MySQL، وهو النظام الذي تستخدمه جميع مواقع ويكيميديا، لكن أنظمة إدارة قواعد البيانات الأخرى (مثل PostgreSQL وOracle وSQLite) لديها تطبيقات مدعومة من المجتمع. يمكن لمسؤول النظام اختيار نظام إدارة قواعد البيانات (DBMS) أثناء تثبيت ميدياويكي، ويوفر MediaWiki كلا من تجريد قاعدة البيانات وطبقة تجريد الاستعلام التي تبسط الوصول إلى قاعدة البيانات للمطورين.

يحتوي التخطيط الحالي على عشرات الجداول. العديد منها يتعلق بمحتوى الويكي (على سبيل المثال ،  ،  ، و  ). الجداول الأخرى تشمل بيانات عن المستخدمين ، الملفات الإعلامية  ، التخزين الآلي  والأدوات الداخلية (  لصف العمل) ، بين أمور أخرى. يتم استخدام الفهارس والجداول التلخيصية على نطاق واسع في ميدياويكي، نظرًا لأن استعلامات SQL التي تفحص عددًا كبيرًا من الصفوف يمكن أن تكون مكلفة للغاية، خاصة على مواقع ويكيميديا. عادةً ما يتم تثبيط الاستعلامات غير المفهرسة.

مرت قاعدة البيانات بالعشرات من تغييرات المخطط على مر السنين، أبرزها هو فصل تخزين النص وتتبع المراجعة في ميدياويكي 1.5.



في النموذج 1.4، تم تخزين المحتوى في جدولين مهمين،  (الذي يحتوي على النص والبيانات المعدلة الحالية للصفحة) و   (الذي يتضمن مراجعات سابقة) ؛ تم الحفاظ على الصفحات الممسوحة في. عندما تم إجراء تعديل، تم نسخ المراجعة الحالية السابقة إلى الجدول ، وتم حفظ التعديل الجديد في. عند إعادة تسمية الصفحة، كان لا بد من تحديث عنوان الصفحة في البيانات التعريفية لجميع مراجعات ، وهو ما قد يستغرق وقتًا طويلاً. عندما يتم حذف صفحة ما، يجب نسخ إدخالاتها في الجدولين  و  إلى الجدول   قبل حذفها؛ وهذا يعني نقل نص جميع المراجعات، وهو ما قد يكون كبيرًا جدًا وبالتالي يستغرق وقتًا.

في النموذج 1.5، تم تقسيم بيانات تعريف المراجعة ونص المراجعة: تم استبدال الجدولين  و  بـ   (بيانات تعريف الصفحات)، و  (بيانات تعريف جميع المراجعات، القديمة أو الحالية) و  (نص جميع المراجعات، القديمة أو الحالية أو تم الحذف). الآن، عند إجراء التحرير، لا يلزم نسخ بيانات تعريف المراجعة حول الجداول: يكفي إدراج إدخال جديد وتحديث المؤشر. بالإضافة إلى ذلك، لم تعد بيانات تعريف المراجعة تتضمن عنوان الصفحة بعد الآن، بل معرفها فقط: وهذا يلغي الحاجة إلى إعادة تسمية جميع المراجعات عند إعادة تسمية الصفحة.

يقوم الجدول  بتخزين البيانات الوصفية لكل مراجعة، ولكن ليس النص الخاص بها؛ بدلاً من ذلك، تحتوي على معرف نصي يشير إلى الجدول  ، الذي يحتوي على النص الفعلي. عند حذف صفحة، يظل نص جميع مراجعات الصفحة موجودًا ولا يلزم نقله إلى جدول آخر. يتكون الجدول  من تعيين المعرفات إلى النقط النصية؛ يشير حقل العلامات إلى ما إذا كان النص الثنائي الكبير مضغوطًا بواسطة gzipp (لتوفير المساحة) أو إذا كان النص الثنائي الكبير مجرد مؤشر إلى وحدة تخزين نص خارجية. تستخدم مواقع ويكيميديا ​​مجموعة تخزين خارجية مدعومة من MySQL مع نقاط من بضع عشرات من المراجعات. يتم تخزين المراجعة الأولى للنقطة بالكامل، ويتم تخزين المراجعات التالية لنفس الصفحة على هيئة اختلافات مقارنة بالمراجعة السابقة؛ ثم يتم ضغط النقط بواسطة gzipped. ونظرًا لأنه يتم تجميع المراجعات في كل صفحة، فإنها تميل إلى أن تكون متشابهة، وبالتالي تكون الاختلافات صغيرة نسبيًا ويعمل gzip بشكل جيد. نسبة الضغط التي تم تحقيقها على مواقع ويكيميديا تقترب من 98٪.

ويكي ويكي أيضاً دعم مدمج لتحقيق التوازن الحملي، و أضاف في وقت مبكر من عام 2004 في ميديا ويكي 1.2 (عندما حصلت ويكي ويكي على خادمها الثاني - وهو أمر كبير في ذلك الوقت). ميزان الحمل (رمز PHP من ميديا ويكي الذي يقرر إلى أي خادم للاتصال) هو الآن جزء حاسم من بنية تحتية ويكيميديا، والذي يفسر تأثيره على بعض قرارات الخوارزمية في الرمز. يمكن لمسؤول النظام أن يحدد في إعدادات ميدياويكي أن هناك خادم قاعدة بيانات رئيسي واحد، وأي عدد من خوادم قاعدة البيانات التابعة؛ يمكن تعيين وزن لكل خادم. سيقوم موازن التحميل بإرسال جميع عمليات الكتابة إلى المعلم، وسيقوم بموازنة القراءات وفقًا للأوزان. كما أنه يتتبع تأخر النسخ المتماثل لكل عبد. إذا تجاوزت فترة تأخير نسخ العبد 30 ثانية، فلن تتلقى أي استفسارات قراءة للسماح لها بالتحقيق؛ إذا تأخرت جميع العبيد أكثر من 30 ثانية، فسوف تضع ميديا ويكي نفسها تلقائياً في وضع القراءة فقط.

يضمن "حامي التسلسل الزمني" الخاص بميدياويكي ألا يتسبب تأخر النسخ مطلقًا في رؤية المستخدم لصفحة تدعي أن الإجراء الذي قام به للتو لم يحدث بعد. يتم ذلك عن طريق تخزين منصب السيد في جلسة المستخدم إذا أدى الطلب الذي قدمه إلى استعلام كتابة. في المرة التالية التي يقدم فيها المستخدم طلب قراءة، يقرأ موازن التحميل هذا الموضع من الجلسة، ويحاول تحديد تابع وصل إلى موضع النسخ المتماثل هذا لخدمة الطلب. إذا لم يكن هناك شيء متاح، فسوف ينتظر حتى يتوفر واحد. قد يبدو الأمر للمستخدمين الآخرين كما لو أن الإجراء لم يحدث بعد، لكن التسلسل الزمني يظل ثابتًا لكل مستخدم.



الطلبات والتخزين المؤقت والتسليم


سير عمل تنفيذ طلب الويب
هو نقطة الوصول الرئيسية لميدياويكي، ويتعامل مع معظم الطلبات التي تتم معالجتها بواسطة خوادم التطبيقات (أي الطلبات التي لم يتم تقديمها بواسطة البنية التحتية التخزين المؤقت؛ انظر أدناه). يقوم الكود الذي تم تنفيذه من  بإجراء فحوصات أمنية، وتحميل إعدادات التكوين الافتراضية من  ، وتخمين التكوين باستخدام  ، ثم تطبيق إعدادات الموقع الموجودة في. ثم يقوم بعد ذلك بإنشاء كائن  ، وإنشاء كائن    اعتمادًا على العنوان ومعلمات الإجراء من الطلب.

يمكن أن يتخذ  مجموعة متنوعة من معلمات الإجراء في طلب URL؛ الإجراء الافتراضي هو  ، والذي يوضح العرض العادي لمحتوى المقالة. على سبيل المثال، يعرض الطلب  محتوى مقالة "Apple" على ويكيبيديا الإنجليزية. تتضمن الإجراءات المتكررة الأخرى  (لفتح مقال لتحريره)، و  (لمعاينة مقال أو حفظه)، و3$ (لإظهار سجل المقالة)، و4$ (لإضافة مقال إلى قائمة مراقبة المستخدم). تشمل الإجراءات الإدارية  (لتحذيف مقالة) و   (لتحظر تحرير مقالة).

ثم يتم الاتصال بـ  لتعامل معظم طلبات URL. فهو يتحقق من العناوين السيئة، وقيود القراءة، وعمليات إعادة التوجيه المحلية بين الويكي، وحلقات إعادة التوجيه، ويحدد ما إذا كان الطلب مخصصًا لصفحة عادية أو خاصة.

يتم تسليم طلبات الصفحة العادية إلى, لإنشاء كائن $ 2 للصفحة , ثم إلى $ 4, التي تتعامل مع "المعيار" الإجراءات. بمجرد اكتمال الإجراء، يقوم  بتحقيق النهاية في الطلب من خلال إجراء معاملات DB، وإخراج HTML وإطلاق التحديثات المؤجلة من خلال صف العمل. ينفذ التحديثات المؤجلة ويغلق المهمة بأمان.

إذا كانت الصفحة المطلوبة عبارة عن صفحة خاصة (أي ليست صفحة محتوى ويكي عادية، ولكنها صفحة خاصة متعلقة بالبرمجيات مثل )، فسيتم استدعاء   بدلاً من  ؛ ثم يتم استدعاء البرنامج النصي PHP المقابل. يمكن للصفحات الخاصة أن تفعل كل أنواع الأشياء السحرية، ولكل منها غرض محدد، وعادة ما يكون مستقلاً عن أي مقالة أو محتواها. تتضمن الصفحات الخاصة أنواعًا مختلفة من التقارير (التغييرات الأخيرة والسجلات والصفحات غير المصنفة) وأدوات إدارة wiki (كتل المستخدم وتغييرات حقوق المستخدم) وغيرها. يعتمد سير عمل التنفيذ على وظيفتهم.

تحتوي العديد من الوظائف على رمز إنشاء ملفات التعريف، مما يجعل من الممكن متابعة سير عمل التنفيذ لتصحيح الأخطاء، في حالة تمكين إنشاء ملفات التعريف. يتم تصميم الملفات الشخصية عن طريق استدعاء وظائف  و   لبدء وتوقف تصميم المفردات على التوالي؛ كل من وظائف تأخذ اسم الوظيفة كمعيار. في مواقع ويكيميديا، يتم إجراء التنميط لنسبة مئوية من جميع الطلبات، للحفاظ على الأداء. يرسل ميدياويكي حزم UDP إلى خادم مركزي يجمعها وينتج بيانات ملفات التعريف.



تجميع صفحة غير مخزنة مؤقتًا
عند عرض صفحة ما، قد يتم أخذ كود HTML من ذاكرة التخزين المؤقت (انظر أدناه)؛ إذا لم يكن الأمر كذلك، يتم أولاً توسيع القوالب ووظائف المحلل اللغوي والمتغيرات. هذا يعطي النص النصي المتوسع ، وهو نتيجة متوسطة يمكن رؤيتها مع $ 1 ، ويعتمد على:
 * النص الإلكتروني؛
 * القوالب المشار إليها بشكل مباشر أو غير مباشر؛
 * وظائف المحلل اللغوي المشار إليها بشكل مباشر أو غير مباشر؛
 * قيم المتغيرات المشار إليها بشكل مباشر أو غير مباشر.

بعد ذلك، يتم تحويل نص الويكي الموسع هذا إلى كود HTML؛ يتم إرساله إلى المستخدم، ويحتوي على إشارات إلى ملفات CSS وJavaScript وملفات الصور. يمكن للمستخدم رؤية هذه النتيجة المتوسطة من خلال تطبيق خيار "عرض المصدر" في المتصفح. يعتمد كود HTML لصفحة معينة على:
 * ونص الويكي الموسع؛
 * الوضع، مثل العرض أو التحرير (انظر أدناه)؛
 * وجود صفحات مرتبطة داخليًا (تعطي رابط العرض أو التحرير)؛
 * الجلد وتفضيلات المستخدم الأخرى؛
 * اسم المستخدم
 * حالة المستخدم (المزيد من الروابط إذا كان نظامًا، وما إلى ذلك)؛
 * مساحة الاسم (يحدد الرابط إلى صفحة النقاش، أو في حالة صفحة النقاش، الصفحة المعنية)؛
 * whether the page is watched by the user (gives watch or unwatch link);
 * whether the user's Talk page has been recently edited (gives a message).

Finally, the browser renders the HTML, using the files it refers to. The result the user sees on the screen depends on:
 * the HTML code;
 * files referred to by the HTML code, such as embedded images, server-side CSS files, and JavaScript files;
 * the browser and browser settings, including possibly a local CSS file, and the screen resolution.

If JavaScript is responding to an event such as a mouse click, the page on the screen depends also on these events. This applies, for example, in the case of a sortable table.

When the user selects the edit tab, the wikitext itself is sent to them, of the whole page or of one section only. When the user presses Show preview, their new version of the wikitext is sent to the server, which sends the corresponding new version of the HTML code, which is rendered again and displayed above or below the user's new version of the wikitext (which the server has also returned). After possibly more changes and more previews, the user presses Save page, sending the user's "final" version to the server, which now records the edit and sends the HTML of the new version (again). In some cases an automatic conversion of wikitext also takes place in this stage.

Caching
MediaWiki itself is improved for performance because it plays a central role on Wikimedia sites, but it is also part of a larger operational ecosystem that has influenced its architecture. Wikimedia's caching infrastructure has imposed limitations in MediaWiki; developers worked around the issues, not by trying to shape Wikimedia's extensively optimised caching infrastructure around MediaWiki, but rather by making MediaWiki more flexible, so it could work within that infrastructure, without compromising on performance and caching needs.

On Wikimedia sites, most requests are handled by reverse caching proxies (Squids), and never even make it to the MediaWiki application servers. Squids contain static versions of entire rendered pages, served for simple reads to users who aren't logged in to the site. MediaWiki natively supports Squid and Varnish, and integrates with this caching layer by, for example, notifying them to purge a page from the cache when it has been changed. For logged-in users, and other requests that can't be served by Squids, Squid forwards the requests to the web server (Apache).

The second level of caching happens when MediaWiki renders and assembles the page from multiple objects, many of which can be cached to minimise future calls. Such objects include the page's interface (sidebar, menus, UI text) and the content proper, parsed from wikitext. The in-memory object cache has been available in MediaWiki since the early 1.1 version (2003), and is particularly important to avoid re-parsing long and complex pages.

Login session data can also be stored in memcached, which lets sessions work transparently on multiple front-end web servers in a load-balancing setup (Wikimedia heavily relies on load balancing, using LVS with PyBal).

Since version 1.16, MediaWiki uses a dedicated object cache for localised UI text; this was added after noticing that a large part of the objects cached in memcached consisted of UI messages localised into the user's language. The system is based on fast fetches of individual messages from constant databases (CDB), i.e. files with key-value pairs. CDBs minimise memory overhead and start-up time in the typical case; they're also used for the interwiki cache.

The last caching layer consists of the PHP opcode cache, commonly enabled to speed up PHP applications. Compilation can be a lengthy process; to avoid compiling PHP scripts into opcode every time they're invoked, a PHP accelerator can be used to store the compiled opcode and execute it directly without compilation. MediaWiki will "just work" with many accelerators such as APC, PHP accelerator.

Because of its Wikimedia bias, MediaWiki is optimised for this complete, multi-layer, distributed caching infrastructure. Nonetheless, it also natively supports alternate setups for smaller sites. For example, it offers an optional simplistic file caching system that stores the output of fully rendered pages, like Squid does. Also, MediaWiki's abstract object caching layer lets it store the cached objects in several places, including the file system, the database, or the opcode cache.

Like in many web applications, MediaWiki's interface has become more interactive and responsive over the years, mostly through the use of JavaScript. Usability efforts initiated in 2008, as well as advanced media handling (e.g. online editing of video files), called for dedicated front-end performance improvements.

To optimise the delivery of JavaScript and CSS assets, the ResourceLoader module was developed. Started in 2009, it was completed in 2011 and has been a core feature of MediaWiki since version 1.17. ResourceLoader works by loading JS and CSS assets on demand, thus reducing loading and parsing time for unused features, for example in older browsers. It also minifies the code, groups resources to save requests, and can embed images as data URIs.

Context and rationale
A central part of effectively contributing and disseminating free knowledge to all is to provide it in as many languages as possible. Wikipedia is available in more than 280 languages, and encyclopedia articles in English represent less than 20 % of all articles. Because Wikipedia and its sister sites exist in so many languages, it is important not only to provide the content in the readers' native language, but also to provide a localised interface, and effective input and conversion tools, so that participants can contribute content.

For this reason, localisation and internationalisation (l10n & i18n) are a central component of MediaWiki. The i18n system is pervasive, and impacts many parts of the software; it's also one of the most flexible and feature-rich. Translator convenience is usually preferred to developer convenience, but this is believed to be an acceptable cost.

MediaWiki is currently localised in more than 350 languages, including non-latin and right-to-left (RTL) languages, with varying levels of completion. The interface and content can be in different languages, and can have mixed directionality.

Content language
MediaWiki originally used per-language encoding, which led to a lot of issues; for example, foreign scripts could not be used in page titles. UTF-8 was adopted instead. Support for character sets other than UTF-8 was dropped in 2005, along with the major database schema change in MediaWiki 1.5; content must now be encoded in UTF-8.

Characters not available on the editor's keyboard can be customised and inserted via MediaWiki's, an interface message that appears below the edit window; its JavaScript version automatically inserts the character clicked into the edit window. The extension for MediaWiki, developed as part of a usability effort, merges special characters with the edit toolbar. Another extension, called, provides additional input methods and key mapping features for non-ASCII characters.

Recent and future improvements include better support for right-to-left text, bidirectional text (LTR and RTL text on the same page) and.

Interface language
Interface messages have been stored in PHP arrays of key-values pairs since the Phase III software was created. Each message is identified by a unique key, which is assigned different values across languages. Keys are determined by developers, who are encouraged to use prefixes for extensions; for example, message keys for the UploadWizard extension will start with, where   stands for MediaWiki extension.

MediaWiki messages can embed parameters provided by the software, which will often influence the grammar of the message. In order to support virtually any possible language, MediaWiki's localisation system has been improved and complexified over time to accommodate their specific traits and exceptions, often considered oddities by English speakers.

For example, adjectives are invariable words in English, but languages like French require adjective agreement with nouns. If the user profile has gender preferences set, the  switch can be used in interface messages to appropriately address them (more info). Other switches include, for "simple" plurals and languages like Arabic with dual, trial or paucal numbers, and  , providing grammatical transformation functions for languages like Finnish whose grammatical cases cause alterations or inflections.

The gender distinction can also be used in gender-dependent user namespace names, so that the title and URL of the page refers to the user correctly. Standard MediaWiki namespaces' gender variants are defined via  in each language's MessagesXx.php, while  can be used for wiki-specific namespaces. As of, 13 languages use this feature by default:



Localising messages
Localised interface messages for MediaWiki reside in  files, where   is the ISO-639 code of the language (e.g.   for French); default messages are in English and stored in. MediaWiki extensions use a similar system, or host all localised messages in an file. Along with translations, Message files also include language-dependent information such as date formats.

Contributing translations used to be done by submitting PHP patches for the  files. In December 2003, MediaWiki 1.1 introduced "database messages", a subset of wiki pages in the MediaWiki namespace containing interface messages. The content of the wiki page is the message's text, and overrides its value in the PHP file. Localised versions of the message are at, e.g..

This feature has allowed power users to translate (and customise) interface messages locally on their wiki, but the process doesn't update i18n files shipping with MediaWiki. In 2006, Niklas Laxström created a special, heavily hacked MediaWiki website (now hosted at ) where translators can easily localise interface messages in all languages, simply by editing a wiki page. The  files are then updated in the MediaWiki code repository, where they can be automatically fetched by any wiki, and updated using the LocalisationUpdate extension. On Wikimedia sites, database messages are now only used for customisation, and not for localisation any more. MediaWiki extensions and some related programs, such as bots, are also localised at translatewiki.net.

To help translators understand the context and meaning of an interface message, it is considered a good practice in MediaWiki to provide documentation for every message. This documentation is stored is a special Message file, with the  language code, which doesn't correspond to a real language. The documentation for each message is then displayed in the translation interface on translatewiki.net. Another helpful tool is the  language code: when used with the   parameter to display a wiki page (e.g.  ), MediaWiki will display the message keys instead of their values in the user interface; this is very useful to identify which message to translate or change.

Registered users can set their own interface language in their preferences, in which case it overrides the site's default interface language. MediaWiki also supports fallback languages: if a message isn't available in the chosen language, it will be displayed in the closest possible language, and not necessarily in English. For example, the fallback language for Breton is French.

Users
Users are represented in the code using instances from the  class, which encapsulates all of the user-specific settings (user id, name, rights, password, email address, etc.). Client classes use accessors to access these fields; they do all the work of determining whether the user is logged in, and whether the requested option can be satisfied from cookies or whether a database query is needed. Most of the settings needed for rendering normal pages are set in the cookie to minimise use of the database.

MediaWiki provides a very granular permissions system, with basically a user permission for every possible action. For example, to perform the "Rollback" action (i.e. to "quickly rollback the edits of the last user who edited a particular page"), a user needs the  permission, included by default in MediaWiki's   user group. But it can also be added to other user groups, or have a dedicated user group only providing this permission (this is the case on the English Wikipedia, with the  group). Customisation of user rights is done by editing the  array in  ; for instance,   allows all registered users to rename files. A user can belong to several groups, and inherits the highest rights associated with each of them.

However, MediaWiki's user permissions system was really designed with Wikipedia in mind, i.e. a site whose content is accessible to all, and only certain actions are restricted to some users. MediaWiki lacks a unified, pervasive permissions concept; it doesn't provide traditional CMS features like restricting read or write access by namespace, category, etc. A few MediaWiki extensions provide such features to some extent.

Content structure
The concept of namespaces was used in the UseModWiki era of Wikipedia, where talk pages were at the title "". Namespaces were formally introduced in Magnus Manske's first "PHP script". They were reimplemented a few times over the years, but have kept the same function: to separate different kinds of content. They consist of a prefix, separated from the page title by a colon (e.g.  or   and  ); the main content namespace has no prefix. Wikipedia users quickly adopted them, and they provided the community with different spaces to evolve. Namespaces have proven to be an important feature of MediaWiki, as they create the necessary preconditions for a wiki's community and set up meta-level discussions, community processes, portals, user profiles, etc.

The default configuration for MediaWiki's main content namespace is to be flat (no subpages), because it's how Wikipedia works, but it is trivial to enable them. They are enabled in other namespaces (e.g., where people can for instance work on draft articles) and display breadcrumbs.

Namespaces separate content by type; within a same namespace, pages can be organised by topic using categories, a pseudo-hierarchical organisation scheme introduced in MediaWiki 1.3.

Content processing: MediaWiki markup language & Parser
The user-generated content stored by MediaWiki isn't in HTML, but in a markup language specific to MediaWiki, sometimes called "wikitext". It allows users to make formatting changes (e.g. bold, italic using quotes), add links (using square brackets), include templates, insert context-dependent content (like a date or signature), and make an incredible number of other magical things happen.

To display a page, this content needs to be parsed, assembled from all the external or dynamic pieces it calls, and converted to proper HTML. The parser is one of the most essential parts of MediaWiki, which also makes it difficult to change or improve. Because hundreds of millions of wiki pages worldwide depend on the parser to continue outputting HTML the way it always has, it has to remain extremely stable.

The markup language wasn't formally spec'd from the beginning; it started based on UseModWiki's markup, then morphed and evolved as needs have demanded. For example, the usage of a ThreadMode format for discussions made Magnus Manske implement the 3 or 4 tildes ( ~ ) as a shortcut to sign one's posts in unstructured text. Tildes were chosen as it resembled his father's hand-written signature.

In the absence of a formal specification, the MediaWiki markup language has become a complex and idiosyncratic language, basically only compatible with MediaWiki's parser; it can't be represented as a formal grammar using BNF, EBNF or ANTLR syntaxes. The current parser's specification is jokingly referred to as "whatever the parser spits out from wikitext, plus a few hundred test cases".

There have been many attempts at alternative parsers, but none has succeeded so far. In 2004, an experimental tokeniser was written by Jens Frank to parse wikitext, and enabled on Wikipedia; it had to be disabled three days later, because of the poor performance of PHP array memory allocations. Since then, most of the parsing has been done with a huge pile of regular expressions, and a ton of helper functions. The wiki markup, and all the special cases the parser needs to support, have also become considerably more complex, making future attempts even more difficult.

A notable improvement was Tim Starling's preprocessor rewrite in MediaWiki 1.12, whose main motivation was to improve the parsing performance on pages with complex templates. The preprocessor converts wikitext to an XML DOM tree representing parts of the document (template invocations, parser functions, tag hooks, section headings, and a few other structures), but can skip "dead branches" in template expansion, such as unfollowed  cases and unused defaults for template arguments. The parser then iterates through the DOM structure and converts its content to HTML.

Recent work on a visual editor for MediaWiki has made it necessary to improve the parsing process (and make it faster), so work has resumed on the parser and intermediate layers between MediaWiki markup and final HTML (see Future, below).

Magic words and templates
MediaWiki offers "Magic words" that modify the general behaviour of the page or include dynamic content into it. They consist of: behaviour switches like  (to hide the automatic table of content) or   (to tell search engines not to index the page); variables like   or  ; and parser functions, i.e. magic words that can take parameters, like   (to output   in lowercase). Constructs like,   and  , used to localise the UI, are parser functions.

The most common way to include content from other pages in a MediaWiki page is to use templates. Templates were really intended to be used to include the same content on different pages, e.g. navigation panels or maintenance banners on Wikipedia articles; having the ability to create partial page layouts and reuse them in thousands of articles with central maintenance made a huge impact on sites like Wikipedia.

However, templates have also been used (and abused) by users for a completely different purpose. MediaWiki 1.3 made it possible for templates to take parameters that change their output; the ability to add a default parameter (introduced in MediaWiki 1.6) enabled the construction of a functional programming language implemented on top of PHP, which was ultimately one of the most costly features in terms of performance.

Tim Starling then developed additional parser functions (the ParserFunctions extension), as a stopgap measure against insane constructs created by Wikipedia users with templates. This set of functions included logical structures like  and , and other functions like   (to evaluate mathematical expressions) and   (for time formatting).

Soon enough, Wikipedia users started to create even more complex templates using the new functions, which considerably degraded the parsing performance on template-heavy pages. The new preprocessor introduced in MediaWiki 1.12 (a major architectural change) was implemented to partly remedy this issue. Later, MediaWiki developers discussed the possibility of using an actual scripting language to improve performance. was added in February of 2013.

Media files
Users upload files through the  page; administrators can configure the allowed file types through an extension whitelist. Once uploaded, files are stored in a folder on the file system, and thumbnails in a dedicated  directory.

Because of Wikimedia's educational mission, MediaWiki supports file types that may be uncommon in other web applications or CMSes, like SVG vector images, and multipage PDFs & DjVus. They are rendered as PNG files, and can be thumbnailed and displayed inline, as are more common image files like GIFs, JPGs and PNGs.

When a file is uploaded, it is assigned a  page containing information entered by the uploader; this is free text, which usually includes copyright information (author, license) and items describing or classifying the content of the file (description, location, date, categories, etc.). While private wikis may not care much about this information, on media libraries like Wikimedia Commons they are critical to organise the collection and ensure the legality of sharing these files. It has been argued that most of these metadata should, in fact, be stored in a queryable structure like a database table. This would considerably facilitate search, but also attribution and reuse by third parties — for example, through the API.

Most Wikimedia sites also allow "local" uploads to each wiki, but the community tries to store freely-licensed media files in Wikimedia's free media library, Wikimedia Commons. Any Wikimedia site can display a file hosted on Commons as if it were hosted locally. This custom avoids having to upload a file to every wiki to use it there.

As a consequence, MediaWiki natively supports foreign media repositories, i.e., the ability to access media files hosted on another wiki through its API and the  system. Since version 1.16, any MediaWiki website can easily use files from Wikimedia Commons through the  feature. When using a foreign repository, thumbnails are stored locally to save bandwidth. However, it is not (yet) possible to upload to a foreign media repository from another wiki.

Levels
MediaWiki's architecture provides different ways to customise and extend the software. This can be done at different levels of access:


 * System administrators can install extensions and skins, and configure the wiki's separate helper programs (e.g. for image thumbnailing and TeX rendering) and global settings (see Configuration above).
 * Wiki sysops (sometimes called "administrators" too) can edit site-wide gadgets, JavaScript and CSS settings.
 * Any registered user can customise their own experience and interface using their preferences (for existing settings, skins and gadgets) or make their own modifications (using their personal JS and CSS pages). External programs can also communicate with MediaWiki through its machine API, if it's enabled, basically making any feature and data accessible to the user.

JavaScript and CSS
MediaWiki can read and apply site-wide or skin-wide JavaScript and CSS using custom wiki pages; these pages are in the  namespace, and thus can only be edited by sysops; for example, JavaScript modifications from   apply to all skins, CSS from   applies to all skins, but   only applies to users with the Vector skin.

Users can do the same types of changes, which will only apply to their own interface, by editing subpages of their user page (e.g.  for JavaScript on all skins,   for CSS on all skins, or   for CSS modifications that only apply to the Vector skin).

If the Gadgets extension is installed, sysops can also edit gadgets, i.e. snippets of JavaScript code providing features that can be turned on and off by users in their preferences. Upcoming developments on gadgets will make it possible to share gadgets across wikis, thus avoiding duplication.

This set of tools has had a huge impact and greatly increased the democratisation of MediaWiki's software development. Individual users are empowered to add features for themselves; power users can share them with others, both informally and through globally-configurable sysop-controlled systems. This framework is ideal for small, self-contained modifications, and presents a lower barrier of entry than heavier code modifications done through hooks and extensions.

Extensions and skins
When JavaScript and CSS modifications are not enough, MediaWiki provides a system of hooks that let third-party developers run custom PHP code before, after, or instead of MediaWiki code for particular events. MediaWiki extensions use hooks to plug into the code.

Before hooks existed in MediaWiki, adding custom PHP code meant modifying the core code, which was neither easy nor recommended. The first hooks were proposed and added in 2004 by Evan Prodromou; many more have been added over the years when needed. Using hooks, it is even possible to extend MediaWiki's wiki markup with additional capabilities, using tag extensions.

The extension system isn't perfect: extension registration is based on code execution at startup, rather than cacheable data, which limits abstraction and optimisation and hurts MediaWiki's performance. But overall, the extension architecture is now a fairly flexible infrastructure that has helped make specialised code more modular, keeping the core software from expanding (too) much, and making it easier for third-party users to build custom functionality on top of MediaWiki.

Conversely, it's very difficult to write a new skin for MediaWiki without reinventing the wheel. In MediaWiki, skins are PHP classes each extending the parent  class; they contain functions that gather the information needed to generate the HTML. The long-lived "MonoBook" skin was difficult to customise because it contained a lot of browser-specific CSS to support old browsers; editing the template or CSS required many subsequent changes to reflect the change for all browsers and platforms.

API
The other main access point for MediaWiki, besides, is  , used to access its machine-readable query API (Application Programming Interface).

Wikipedia users originally created "bots" that worked by screen scraping the HTML content served by MediaWiki; this method was very unreliable and broke many times. To improve this situation, developers introduced a read-only interface (located at ), which then evolved into a full-fledged read and write machine API providing direct, high-level access to the data contained in the MediaWiki database.

Client programs can use the API to login, get data, and post changes. The API supports thin web-based JavaScript clients and end-user applications. Almost anything that can be done via the web interface can basically be done through the API. Client libraries implementing the MediaWiki API are available in many languages, including Python and .NET.

Layers, domains, and patterns
MediaWiki can be divided into around 12 technical layers, with each layer calling classes and code in the layer beneath it but not above it. Examples include the installer layer, entry point layer, wiring layer, and API layer. Code spanning all the layers can be grouped into around 21 domain modules, with examples including the navigation domain (skins), user management domain (create, rename, login), and internationalisation domain. Many software design patterns are used in MediaWiki, including the factory pattern, handler pattern, and command pattern.

Future
What started as a summer project done by a single volunteer PHP developer has grown into MediaWiki, a mature, stable wiki engine powering a top-ten website with a ridiculously small operational infrastructure. This has been made possible by constant optimisation for performance, iterative architectural changes and a team of awesome developers.

The evolution of web technologies, and the growth of Wikipedia, call for ongoing improvements and new features, some of which require major changes to MediaWiki's architecture. This is, for example, the case for the ongoing visual editor project, which has prompted renewed work on the parser and on the wiki markup language, the DOM and final HTML conversion.

MediaWiki is a tool that is used for varied purposes. Within Wikimedia projects, for instance, it's used to create and curate an encyclopedia (Wikipedia), to power a huge media library (Wikimedia Commons) or to transcribe scanned reference texts (Wikisource); and so on. In other contexts, MediaWiki is used as a corporate CMS, or as a data repository, sometimes combined with a semantic framework. These specialised uses that weren't planned for will probably continue to drive constant adjustments to the software's internal structure. As such, MediaWiki's architecture is very much alive, just like the immense community of users it supports.