دليل:وسوم الامتدادات

This page is a translated version of the page Manual:Tag extensions and the translation is 100% complete.
امتدادات ميدياويكي

غالبا ما ستجد بعض المشاريع وحدها أنه من المفيد توسيع وسم الويكي المدمج باستخدام إمكانات إضافية، سواء كانت من ناحية معالجة السطور البرمجية البسيطة وصولا إلى سبل استرداد معلومات كاملة. تسمح امتدادات الوسوم للمستخدمين إنشاء وسوم جديدة مخصصة تفعل ما ذكرناه هنا. يمكن للمرء على سبيل المثال استخدام امتداد وسوم كي يضيف وسم ‎‎<donation /> بسيط يعمل على إضافة نموذج تبرع إلى صفحة ما. إن الامتداد جنبا إلى جنب مع دوال المعرب اللغوي والروابط هي أفضل سبيل لتغيير وظائف برمجيات ميدياويكي أو تحسينها. عليك دائما التحقق من المصفوفة قبل الشروع في العمل على امتداد ما كي تتأكد أنه لا يوجد شخص آخر فعل ما سوف تشرع في عمله.

يتألف امتداد وسوم بسيط من دالة استدعاء التي توصل بالمعرب اللغوي حتى يتمكن حينما يعمل المعرب اللغوي من البحث عن كافة حالات ذكر وسم معين واستبداله وبالتالي استدعاء دالة الاستدعاء المعنية كي عرض صيغة إتش تي إم إل الفعلية.

مثال

في extension.json، اضبط الوصلات:

...
  "Hooks": {
    "ParserFirstCallInit": "ExampleExtension::onParserFirstCallInit"
   },
...

ثم أضف الوصلة إلى ملف بي إتش بي

<?php

class ExampleExtension {
	// تسجيل أي حالات استدعاء عرض مستخدما المعرب اللغوي
	public static function onParserFirstCallInit( Parser $parser ) {
		// حينما يجد المعرب اللغوي وسم <sample> سوف ينفذ renderTagSample (طالع ما يلي)
		$parser->setHook( 'sample', [ self::class, 'renderTagSample' ] );
	}

	// Render <sample>
	public static function renderTagSample( $input, array $args, Parser $parser, PPFrame $frame ) {
		// لا يوجد ما يثير الدهشة هنا، كل ما عليك هو الابتعاد عن المدخلات التي أضافها المستخدم ومن ثم عرضها مرة أخرى (حسب المثال)
		return htmlspecialchars( $input );
	}
}

يسجل هذا المثال دالة استدعاء من أجل وسم ‎‎<sample>. حينما يضيف مستخدم هذا الوسم إلى صفحة مثل هذه: ‎<sample arg1="xxx" arg2="xxx">...input...</sample>، سيتولى المعرب اللغوي استدعاء دالة ‎renderTagSample()‎ ومن ثم تمرير أربعة متغيرات:

$input
مدخلات بين وسوم ‎‎<sample> و‎‎</sample> أو null لو كان الوسم «مغلق - closed» أي ‎‎<sample />
$args
متغيرات الوسوم، التي تدخل كما يجري إدخال نعوت وسوم إتش تي إم إل؛ هذه هي سلسلة مترابطة تفهرس حسب اسم النعت.
$parser
المعرب اللغوي الرئيسي (كائن المعرب اللغوي)؛ تستخدم الامتدادات المتقدمة المستوى هذه كي تحصل على العنوان حسب السياق وكذلك إعراب نصوص الويكي وتوسيع الأقواس وتسجيل علاقات الوصلات واعتمادها على بعضها البعض وخلافه.
$frame
الهيكل الرئيسي (عنصر PPFrame). يستخدم جنبا إلى جنب مع $parser لأغراض تزويد المعرب اللغوي بمعلومات كاملة عن السياق الذي استدعي فيه الامتداد.

لمزيد من الأمثلة المفصلة، طالع مثال امتداد الوسوم

النعوت

هيا بنا نشاهد مثال آخر:

<?php

$wgHooks['ParserFirstCallInit'][] = 'onParserFirstCallInit';

function onParserFirstCallInit( Parser $parser ) {
	$parser->setHook( 'sample', 'wfSampleRender' );
}

function wfSampleRender( $input, array $args, Parser $parser, PPFrame $frame ) {
	$attr = [];    
	// هذه المرة ضع قائمة بالنعوت وقيمها ومن ثم إضافتها جنب إلى جنب مع مدخلات المستخدم
	foreach( $args as $name => $value ) {
		$attr[] = '<strong>' . htmlspecialchars( $name ) . '</strong> = ' . htmlspecialchars( $value );
	}
	return implode( '<br />', $attr ) . "\n\n" . htmlspecialchars( $input );

/**
 * يمكن استخدام السطور التالية للحصول على قيم المتغيرات مباشرة:
 * $to = $args['to'] ;
 * $email = $args['email'] ;
 */
}

يضيف هذا المثال النعوت التي مررت إلى الوسم مع قيمها. لا جدال أن هذا الأمر يسمح بوجود تحديد مرن للوسوم الجديدة والمخصصة. ربما تحدد على سبيل المثال امتداد وسوم يسمح للمستخدم بإضافة نموذج اتصال إلى صفحة المستخدم ذاته، مستخدما كود برمجي كالتالي ‎<emailform to="User" email="user@foo.com" />.

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

الأعراف

طالع ‎Manual:Developing extensions لتتعرف على الهيئة العامة وكيفية تنصيب امتداد.

نشر امتداداتك

  1. أنشئ صفحة جديدة على موقع الويكي هذا تحمل اسم Extension:<extension_name>‎ تحمل معلومات عن امتدادك وكيفية تنصيبه ولقطات من الشاشة أثناء استخدامه. يوجد قالب مؤاتي جاهز لإضافة تلك المعلومات يحمل اسم ‎قالب:امتداد . طالع صفحة القالب لتطلع على مزيد من المعلومات. يتعين عليك أيضا أن تضيف أكبر كم ممكن من التفاصيل إلى متن الصفحة ومن الحصيف أن تزور الصفحة تكرارا كي ترد على أسئلة المستخدمين على صفحة النقاش الملحقة. تأكد أيضا من أن الصفحة أضيفت إلى ‎تصنيف:امتدادات .
  2. يجب أن تسجل الامتدادات التي تحدد وصلات جديدة داخل كود الامتداد البرمجي في صفحة تصنيف وصلات الامتدادات.
  3. أبلغ القائمة البريدية mediawiki-l.

طالع أيضا نشر امتدادك.

الأسئلة الشائعة

بواعث قلق تتعلق بالأمن

سوف تلاحظ فيما سبق أن المدخلات في الأمثلة سالفة الذكر تغفل باستخدام ‎htmlspecialchars() قبل رجوعها. من الأهمية بمكان أن تعامل كافة مدخلات المستخدم بهذه الطريقة قبل ردها إلى جهاز العميل وذلك لتجنب إضافة محاور حقن برمجة اعتباطية قد تؤدي إلى حدوث ثغرات أمنية بسبب البرمجة على أكثر من موقع.

تحميل الوحدات البرمجية

إن أفضل سبيل لإضافة الوحدات البرمجية إلى امتدادك هو إضافتها إلى ‎ParserOutput لا إلى ‎$wgOut. من ثم سوف تؤخذ قائمة الوحدات البرمجية آليا من عنصر ‎ParserOutput وتضاف إلى ‎$wgOut حتى حينما يكون عرض الصفحة محفوظ في الحفظ المؤقت مسبقا. لو كنت تضيف الوحدات البرمجية مباشرة إلى ‎$wgOut قد لا تحفظ حفظا مؤقتا في مخرجات المعرب اللغوي.

function myCoolHook( $text, array $params, Parser $parser, PPFrame $frame ) {
	// ... تفعل أشياء ...
	$parser->getOutput()->addModules( 'ext.mycoolext' );
	$parser->getOutput()->addModuleStyles( 'ext.mycoolext.styles' );
	// ... تفعل المزيد من الأشياء ...
}

التوقيت والامتدادات

لو غيرت الكود المصدري لأي امتداد، سوف تعرض كافة الصفحات التي تستعين بالامتداد آليا على الفور نتائج الكود المصدري الجديد. من الناحية الفنية، يعني هذا أن كودك المصدري ينفذّ كل مرة تعرض فيها صفحة تحتوي على الامتداد.

ومن الناحية العملية، غالبا ما لا يكون الأمر كما سلف، بسبب الحفظ المؤقت للصفحة – سواء في برمجيات ميدياويكي أو متصفح الإنترنت أو بروكسي وسيط أو جدار ناري.

كي تتخطى الحفظ المؤقت للمعرب اللغوي لميدياويكي والتأكد أن النسخة الجديدة من الصفحة تولّد، اضغط على تعديل ومن ثم ضع محل "action=edit"في معرف الموارد الموحد المبين في سطر العنوان من متصفحك "action=purge" ومن ثم إرسال معرف الموارد الموحد الجديد. بهذه الطريقة سوف يعاد توليد الصفحة وكافة القوالب المذكورة فيها وبالتالي تجاهل كافة البيانات المحفوظة حفظا مؤقتا. يحتاج الأمر استخدام فعل تنظيف الحفظ المؤقت لو كانت الصفحة الرئيسية ذاتها لم يجري عليها تعديل، إلا أن الطريقة التي يتعين بها عرضها قد تغيرت (جرى على الامتداد تعديل أو مجرد تعديل قالب مذكور).

إن لم يكن هذا كافيا للحصول على نسخة حديثة من الصفحة، يمكنك في المعتاد تجاوز الحفظ المؤقت الوسيط عن طريق إضافة '&rand=somerandomtext' إلى نهاية معرف الموارد الموحد المذكور. احرص على أن يكون 'somerandomtext' مختلفا في كل مرة.

كيف أعطل الحفظ المؤقت للصفحات التي تستخدم امتدادي؟

منذ إصدار ميدياويكي 1.5، يمر المعرب اللغوي بصفته المتغير الثالث في أي امتداد. يمكن استخدام المعرب اللغوي في أغراض تعطيل الحفظ المؤقت كما يلي:

function wfSampleSomeHookFunction( $text, array $args, Parser $parser, PPFrame $frame ) {
	$parser->getOutput()->updateCacheExpiry(0);
	// ...
}

إعادة توليد الصفحة حينما يجري تعديل على صفحة أخرى

يجوز أنك لا ترغب في تعطيل الحفظ المؤقت كلية بل مجرد إعادة توليد الصفحة حينما يجري تعديل صفحة أخرى، كما هو الحال في كيفية التعامل مع أعمال تضمين القوالب. يمكن تنفيذ ذلك مستخدما عنصر المعرب اللغوي الذي يمرر إلى دالة الربط التي تستخدمها. رفعت الطريقة التالية من ملف CoreParserFunctions.php ويبدو أنها تعمل على ما يرام لهذا الغرض.

/** اجعل الصفحة التي يجري ضمها معتمدة على $page مستخدمًا جدول templatelinks. 
*/
function wfSampleaddTemplateLinkDependency( Parser $parser, $page )  {
	$title = Title::newFromText( $page );
	$rev = Revision::newFromTitle( $title );
	$id = $rev ? $rev->getPage() : 0;
	// Register dependency in templatelinks
	$parser->getOutput()->addTemplate( $title, $id, $rev ? $rev->getId() : 0 );
}


التعديل الدقيق للغاية لسلوك الحفظ المؤقت

يمكنك استخدام الحفظ المؤقت الدقيق للغاية مع امتداداتك عن طريق استخدام مفاتيح الحفظ المؤقت كي تفرق بين الإصدارات المختلفة من مخرجات امتدادك. أثناء العرض يمكنك إضافة مفاتيح حفظ مؤقت لكل ميزة عن طريق إضافة طريقة addExtraKey إلى دالة رابطك. إليك مثال:

function wfSampleSomeHookFunction( $text, array $args, Parser $parser, PPFrame $frame ) {
	$userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup();
	$setting1= (int)$userOptionsLookup->getOption( $parser->getUserIdentity(), 'setting1' );
	$parser->getOptions()->optionUsed( 'setting1' );
	$setting2= (int)$userOptionsLookup->getOption( $parser->getUserIdentity(), 'setting2' );
	$parser->getOptions()->optionUsed( 'setting2' );
	...
}

إلا أن تعديل $parser->getOptions() أثناء الإعراب اللغوي يعني أن مفاتيح الخيار الإضافية ليست مشتملة حينما يحاول الحصول على صفحة محفوظة حفظا مؤقتا، بل سوف تشتمل فقط أثناء عرض صفحة بالذهاب إلى الحفظ المؤقت حتى يمكنك استخدام رابط PageRenderingHash لضبط خيارات إضافية. يعمل رابط ‎PageRenderingHash‎ حينما تضع صفحة في الحفظ المؤقت وكذلك إخراجها، لذلك من الأهمية بمكان أن تضع المفاتيح الجديدة إلى الرابط لو لم يوجد رابط قائم من قبل. إليك مثال:

$wgHooks['PageRenderingHash'][] = 'wfMyExtOnPageRenderingHash';

function wfMyExtOnPageRenderingHash( &$confstr, $user, $optionsUsed ) {
	$userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup();
	if ( in_array( 'setting1', $optionsUsed ) ) {
		$confstr .= "!setting1=" . $userOptionsLookup->getOption( $user, 'setting1' );
	}
	if ( in_array( 'setting2', $optionsUsed ) ) {
		$confstr .= "!setting2=" . $userOptionsLookup->getOption( $user, 'setting2' );
	}
}

هذه بعض من الملاحظات الهامة في هذا الشأن:

  • يضمن استخدام "!‎setting1=$value"‎ بدلا من "‎!$value" فقط في confstr أن الحفظ المؤقت للمعرب اللغوي لا يصيبه الاختلال لو نصبّت امتدادات أخرى أو تغير ترتيب تحميلها. يستخدم المحرف ! في صفة فاصل بين خيارات العرض المختلفة
  • يستخدم البعض ‎‎$parser->getOptions()->addExtraKey()‎ بدلا من استخدام ‎‎$parser->getOptions()->optionUsed()‎. يرجى العلم أن إضافة addExtraKey لا يوجه الحفظ المؤقت للمعرب اللغوي إلى أن المفتاح الإضافي مستخدم، وبالتالي قد ينتج عن هذا تعطيل الحفظ المؤقت لو لم تكن حريصا.

كيف أعرض نصوص الويكي في امتدادي؟

منذ الإصدار 1.16

إصدار ميدياويكي:
1.16

تمرر دوال روابط المعرب اللغوي بصفة ذكر لعنصر المعرب اللغوي وعنصر هيكل؛ يجب استخدام هذه في إعراب نصوص الويكي لغويا.

function wfSampleWonderfulHook( $text, array $args, Parser $parser, PPFrame $frame ) {
	$output = $parser->recursiveTagParse( $text, $frame );
	return '<div class="wonderful">' . $output . '</div>';
}

أضيفت ‎Parser::recursiveTagParse‎() منذ الإصدار 1.8. تشتمل مزايا ذلك البساطة (حيث يتطلب الأمر متغير واحد فقط ويكون رده هو سطر) وكذلك حقيقة أنه يعرب وسوم الامتداد لغويا في ‎‎‎$text‎ حتى يمكنك إدخال وسوم الامتداد داخل بعضها البعض.

أما المتغير الثاني في recursiveTagParse وهو ‎‎$frame‎ هو متغير اختياري أضيف إلى نسخة ميدياويكي 1.16 ألفا ‏(‎r55682).

  • لو كان $frame موجود (باستخدام قيمة $frame التي مررت إلى امتدادك)، سوف ينتج عن هذا توسيع أية متغيرات قوالب موجودة في $text. بعبارة أخرى، سوف يجري التعرف على أي محتوى مثل {{{1}}} وسوف يحول إلى القيمة الملائمة للغرض.
  • لو كان $frame غير موجود (مثل $parser->recursiveTagParse( $text ))، أو لو كان $frame مضبوطة قيمته إلى false، لن يجري توسيع متغيرات القالب أي لن يجري أي تغيير على {{{1}}}. رغم أن هذا الأمر يحتمل قليلا جدا أن يكون السلوك المرغوب، كان هذا هو الخيار الوحيد المتاح قبل إصدار ميدياويكي 1.16.

إلا أن خطوة واحدة في الإعراب اللغوي يجري حتى الآن تخطيها في أمور الوسوم حتى لو كنت تستخدم recursiveTagParse هي Parser::preSaveTransform. إن preSaveTransform هي أول خطوة في الإعراب اللغوي وتتولى إجراء تغييرات مستديمة على نص الويكي الذي على وشك لحفظ، كما يلي:

  • تحويل التوقيعات (~~~, ~~~~, ~~~~~)
  • توسيع ملصقات الوصلات، الذي يعرف أيضا باسم pipe-trick (مثال على ذلك تغيير [[Help:Contents|]] إلى [[Help:Contents|Contents]]). دون هذه الخطوة، سوف تعتبر الوصلات مثل [[Help:Contents|]] غير صالحة، ومن ثم تترك في هيئتها نص ويكي حينما يجري إعرابها لغويا.
  • توسيع قوالب {{subst:}}.

يتخطى الاستدعاء الأصلي في preSaveTransform عن قصد حالات التحويل هذه داخل كافة وسوم الامتداد. لو كنت ترغب في أن يجري التحويل قبل الحفظ، عليك أن تفكر جديا في استخدام دالة معرب لغوي بدلا من هذه. يمكن أيضا لكافة امتدادات الوسوم أن تستدعى في صفة دالة معرب لغوي مستخدما {{#tag:tagname|input|attribute_name=value}} وهو الذي سيعمل على تنفيذ التحويل قبل الحفظ.

كيف يمكنني تمرير متغيرات من نوع إكس إم إل في وسوم امتدادي؟

منذ الإصدار 1.5

منذ إصدار ميدياويكي 1.5، أصبح دعم المتغيرات من نوع إكس إم إل (نعوت الوسوم) ممكنا. تمرر المتغيرات في صفة المتغير الثاني إلى دالة الرابط، في هيئة سلسلة مترابطة. سلاسل القيم جرى بالفعل فك تشفير كيانات محارف إتش تي إم إل فيها لأجلك، لذا لو أرسلتها مرة أخرى إلى إتش تي إم إل، لا تنس استخدام htmlspecialchars( ‎$codeToEncode, ENT_QUOTES ) كي تتجنب حدوث حقن لنص إتش تي إم إل برمجي.

كيف يمكنني تجنب حدوث تعديل على مخرجات إتش تي إم إل من امتدادي؟

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

  • استبدال strip markers. إن strip markers هي عناصر محددة تضاف في مراحل مختلفة من معالجة نصوص الويكي وتعمل في صفة مادة معلمة الغرض منها إضافة محتوى محذوف مرة أخرى في وقت لاحق. هذا الأمر ليس أمرا تحتاج الامتدادات للتعامل معه في المعتاد.
  • Parser::doBlockLevels تحوّل محارف * إلى قوائم وتحول أي سطر يبدأ بمسافة إلى ‎‎<pre> وأشياء أخرى. هذا الأمر قد يصبح في بعض الأحيان معضلة لبعض الامتدادات.

كما تساند امتدادات الوسوم رد سلسلة بدلا من مجرد سطر (كما هو الحال في دوال المعرب اللغوي) كي تغير كيفية تفسير القيمة المردودة. يتعين أن تكون القيمة 0 للسلسلة أن تكون بصيغة إتش تي إم إل. يجوز ضبط مفتاح «markerType» ليكون nowiki كي توقف إجراء المزيد من الإعراب اللغوي. عمل شيء ما يشبه return [ $html, 'markerType' => 'nowiki' ]; قد يضمن أن قيمة ‎$html لا تعدل أي تعديل إضافي وتعامل معاملة إتش تي إم إل صرف.

كيف يمكنني جعل امتدادي يظهر في صفحة Special:version؟

كي يظهر امتدادك في صفحة Special:Version في ميدياويكي، يتعين عليك تعيين بيانات حقوق الامتداد داخل كود بي إتش بي البرمجي.

كي تنفذ ذلك، أضف متغير $wgExtensionCredits في صفة أول سطر تنفيذ في الكود البرمجي قبل سطر الوصلة أو تعريف الدالة.

إليك مثال على بيانات حقوق الامتداد:

<?php
/**
 * ExampleExtension - this extension is an example that does nothing
 *
 * To activate this extension, add the following into your LocalSettings.php file:
 * require_once('$IP/extensions/Example.php');
 *
 * @ingroup Extensions
 * @author John Doe <john.doe@example.com>
 * @version 1.0
 * @link https://www.mediawiki.org/wiki/Extension:MyExtension Documentation
 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
 */

/**
 * Protect against register_globals vulnerabilities.
 * This line must be present before any global variable is referenced.
 */
if( !defined( 'MEDIAWIKI' ) ) {
	echo( "This is an extension to the MediaWiki package and cannot be run standalone.\n" );
	die( -1 );
}

// Extension credits that will show up on Special:Version    
$wgExtensionCredits['validextensionclass'][] = array(
	'path'           => __FILE__,
	'name'           => 'Example',
	'version'        => '1.0',
	'author'         => 'John Doe', 
	'url'            => 'https://www.mediawiki.org/wiki/Extension:MyExtension',
	'descriptionmsg' => 'example-desc', // Message key in i18n file.
	'description'    => 'This extension is an example and performs no discernible function'
);

$wgExtensionMessagesFiles[] = __DIR__ . '/Example.i18n.php';

// Here is where we set up our extension
function wfExample(){
	// ...
}

ضع محل validextensionclass واحد مما يلي (إلا لو كان امتدادك ينتمي إلى أكثر من فئة واحدة. في هذه الحالة أنشئ بيانات حقوق لكل فئة على حدة):

  • 'specialpage' مخصص للإضافات إلى صفحات ميدياويكي الخاصة؛
  • 'parserhook' يستخدم لو كان امتدادك يعدل دوال المعرب اللغوي في ميدياويكي أو يكملها أو يحل محلها؛
  • 'variable' امتداد يضيف وظائف متعددة إلى ميدياويكي؛
  • 'media' يستخدم لو كان امتدادك يعمل بشكل أو آخر في صفة امتداد يتعامل مع ملفات وسائط؛
  • 'other' كافة الامتدادات الأخرى.

إن myextensionmsg هو اسم رسالة الواجهة أو التدويل التي تصف امتدادك والتي سوف يتعين عليك أن تحددها في ملف i18n.php في امتدادك. لو حذفت هذه الخانة، سوف تستخدم خانة description بدلا منها.

استرداد اسم الوسم داخل رد الاتصال

لنفترض أن لديك عدة وسوم ‎<foo> و ‎<bar> التي تشترك في ذات رد الاتصال، وداخل دالة رد الاتصال، ترغب في الحصول على اسم الوسم – name of the tag الذي استدعى رد الاتصال.

$wgHooks['ParserFirstCallInit'][] = 'onParserFirstCallInit';

# ...

public function onParserFirstCallInit( Parser $parser ) {
	$parser->setHook( 'foo', 'sharedFunctionality' );
	$parser->setHook( 'bar', 'sharedFunctionality' );
}

# ...

public function sharedFunctionality( $input, array $args, Parser $parser, PPFrame $frame ) {
	// كيف يمكنك التمييز بين طلبات 'foo' وبين 'bar'؟
}

الإجابة المختصرة هي: اسم الوسم (foo أو bar) غير موجود في أي من متغيرات رد الاتصال المستقلة. إلا أنه يمكنك التحايل على هذا الأمر عن طريق تصميم رد اتصال تفاعلي مستقل لكل وسم، كما يلي:

$wgHooks['ParserFirstCallInit'][] = 'onParserFirstCallInit';

# ...

public function onParserFirstCallInit( Parser $parser ) {
	// لكل اسم وسم على حدة
	foreach ( [ 'foo', 'bar' ] as $tagName ) {
		// ينتح عنه استحداث دالة رد اتصال تفاعلية
		$callback = function( $input, $args, $parser, $frame ) use ( $tagName ) {
			// يستدعي رد الاتصال الدالة المشتركة.
			// لاحظ أننا الآن نمرر اسم الوسم في صفة متغير.
			return sharedFunctionality( $input, $args, $parser, $frame, $tagName );
		};
		// تخصيص رد الاتصال إلى الوسم
		$parser->setHook( $tagName, $callback );
	}
}

# ...

public function sharedFunctionality( $input, array $args, Parser $parser, PPFrame $frame, $tagName) {
	// الآن يمكننا استعادة اسم الوسم وتنفيذ تصرفات مخصصة لهذا الوسم
	switch ( $tagName ) {
		//...
	}
}

أزرار شريط الأدوات

امتداد:WikiEditor يقدم شريط أدوات للتعديل، يسمح للمستخدمين إضافة وسوم إلى محرر النصوص لديهم عن بمجرد النقر على زر. لو كنت ترغب في زر شريط أدوات لوسمك الجديد، أنشئ ملف وسمه باسم من قبيل toolbar-button.js في مجلد resources الخاص بامتدادك. سيبدو الملف كما يلي:

var customizeToolbar = function () {
    $('#wpTextbox1').wikiEditor('addToToolbar', {
        section: 'main',
        group: 'format',
        tools: {
            "ExtensionName": { // ضع مكانه اسم امتدادك
                label: 'TagName', // ضع مكانه العنوان الذي يجب أن يظهر حينما تضع المؤشر على الزر
                type: 'button',
                icon: "extensions/ExtensionName/images/button-image.svg", // مسار الصورة التي جب أن تظهر على الزر
                action: {
                    type: 'encapsulate',
                    options: {
                        pre: "<tagName>", // الوسوم التي تدرج حينما يضغط على الزر
                        post: "</tagName>"
                    }
                }
            }
        }
    });
};

/* تحقق من أن حالة العرض هي وضع التعديل وأن الوحدات البرمجية المطلوبة متوفرة. لو كان ذلك صحيحا، تخصيص شريط الأدوات ... */
if ( [ 'edit', 'submit' ].indexOf( mw.config.get( 'wgAction' ) ) !== -1 ) {
    mw.loader.using( 'user.options' ).then( function () {
        // يجوز أن يكون هذا هو السطر «0» لو عطل المستخدم التفضيلات ([[phab:T54542#555387]])
        if ( mw.user.options.get( 'usebetatoolbar' ) == 1 ) {
            $.when(
                mw.loader.using( 'ext.wikiEditor' ), $.ready
            ).then( customizeToolbar );
        }
    } );
}

يمكن الاطلاع على مزيد من التفاصيل عن تخصيص هذا الملف هنا. حال إنشاء الملف، يجب عليك تسجيله مستخدمًا ResourceLoader حتى يمكن عرضه على الزوار؛ ويجري هذا عن طريق تعديل extension.json لديك:

"Hooks": {
    "BeforePageDisplay": "ExtensionName::onBeforePageDisplay"
}
"ResourceModules": {
    "ext.ExtensionName": {
        "scripts": ["toolbarButton.js"]
    }
}

بعد ذلك، في ملف بي إتش بي لديك:

public static function onBeforePageDisplay( OutputPage $out ) {
    $out->addModules( [ 'ext.ExtensionName' ] );
}

طالع أيضا