دليل:دوال المحلل اللغوي

From mediawiki.org
This page is a translated version of the page Manual:Parser functions and the translation is 100% complete.
MediaWiki extensions

إن دوال المحلل اللغوي التي أضيفت في نسخة ميدياويكي 1.7 هي أحد أنواع الامتدادات التي تندمج اندماجا وثيقا مع المحلل اللغوي. يجب ألا تخلط بين عبارة «دوال المحلل اللغوي – parser functions» وبين Extension:ParserFunctions ، التي هي عبارة عن مجموعة من دوال المحلل اللغوي البسيطة. (اذهب إلى Help:Extension:ParserFunctions كي تطالع تلك).

الوصف

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

البنية اللغوية المعتادة لدالة معرب لغوي هي كما يلي:

{{ #functionname: param1 | param2 | param3 }}

لمزيد من المعلومات، طالع التوثيق المخصص لمتغير ‎Parser::setFunctionHook ( $id, $callback, $flags = 0 )‎. تذكر أعمال التوثيق هذه ما يلي:

يجب أن تكون صيغة دالة الاستدعاء كما يلي:
function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }
أو باستخدام SFH_OBJECT_ARGS:
function myParserFunction( $parser, $frame, $args ) { ... }

المتغير الأول للاستدعاء يمرر كافة الطلبات في صيغة نص صرف. The second passes all arguments as an array of PPNode s, except for the first ($args[0]), which is currently text, though this may change in the future. تمثّل هذه نص الويكي غير الموسّع. The $frame parameter can be used to expand these arguments as needed. يستخدم هذا عادة في المعالجة المشروطة حتى يجري تقييم الحالة «الصحيحة» لا غير باستخدام دوال المعرب اللغوي من نوع if-‎ أو switch-‎. يمكن أيضًا لعنصر الإطار الارتقاء في هيكل الوثيقة للحصول على معلومات عن المستدعي وتسخير دوال لتحديد عمق الاستدعاء والوقت المستغرق وما إذا كانت نتائج دوال المعرب اللغوي متغيّرة أم لا وكذلك التعامل مع هذه الأمور.

إن استحداث دالة معرب لغوي معقد قليلًا مقارنة باستحداث وسم جديد لأن اسم الدالة يتعين أن يكون كلمة سحرية، كملة مفتاحية تساند الأسماء المستعارة وأعمال الأقلمة.

مثال بسيط

ما يلي هو مثال على امتداد ينشئ دالة معرب لغوي.

يذهب التسجيل في ملف extension.json ويذهب الكود البرمجي في ملف src/ExampleExtensionHooks.php على الترتيب:

{
	"name": "ExampleExtension",
	"author": "Me",
	"version": "1.0.0",
	"url": "https://www.mediawiki.org/wiki/Extension:ExampleExtension",
	"descriptionmsg": "exampleextension-desc",
	"license-name": "GPL-2.0-or-later",
	"type": "parserhook",
	"MessagesDirs": {
		"ExampleExtension": [
			"i18n"
		]
	},
	"AutoloadClasses": {
		"ExampleExtensionHooks": "src/ExampleExtensionHooks.php"
	},
	"ExtensionMessagesFiles": {
		"ExampleExtensionMagic": "ExampleExtension.i18n.php"
	},
	"Hooks": {
		"ParserFirstCallInit": "ExampleExtensionHooks::onParserFirstCallInit"
	},
	"manifest_version": 1
}
<?php
class ExampleExtensionHooks {
   // تسجيل أي حالات استدعاء عرض مستخدما المعرب اللغوي
   public static function onParserFirstCallInit( Parser $parser ) {

      // يستحدث رابط دالة يربط بين الكلمة المفتاحية «example» وبين ‎renderExample()
      $parser->setFunctionHook( 'example', [ self::class, 'renderExample' ] );
   }

   // يعرض مخرجات {{‎#example:}}.
   public static function renderExample( Parser $parser, $param1 = '', $param2 = '', $param3 = '' ) {

      // مدخلات المتغيرات هي نصوص ويكي توسع فيها القوالب.
      // يجب أن تكون المخرجات هي نصوص ويكي أيضًا.
      $output = "param1 is $param1 and param2 is $param2 and param3 is $param3";

      return $output;
   }
}

يجب أن يحتوي ملف آخر يحمل الاسم ExampleExtension.i18n.php في مجلد الامتدادات لديك (لا في المجلد الفرعي src/) على ما يلي:

<?php
/**
 * @license GPL-2.0-or-later
 * @author Your Name (YourUserName)
 */

$magicWords = [];

/** English
 * @author Your Name (YourUserName)
 */
$magicWords['en'] = [
   'example' => [ 0, 'example' ],
];

حينما يكون هذا الامتداد مفعلًا،

  • {{#example: hello | hi | hey}}

ينتج عنه:

  • param1 is hello and param2 is hi and param3 is hey
إن متوالية magicWords هذه ليست اختيارية. لو محيت، لن تعمل دوال المعرب اللغوي بكل بساطة؛ سوف يعرض {{#example: hello | hi}} كما لو كان الامتداد غير مثبت. لو كانت مصفوفة اللغة المحددة قد بدأت لا مصفوفة الكلمات السحرية ذاتها، يمكن أن ينتج عن هذا أخطاء في الأقلمة منذ أن الترجمات من امتدادات أخرى تتسرب إلى ترجماتك. يمكنك ربط الكلمات السحرية في السطر في بي إتش بي بدلا من استخدام ملف تدويل. هذا الأمر مفيد حينما تعرّف الروابط في ملف LocalSettings.php
MediaWiki\MediaWikiServices::getInstance()->getContentLanguage()->mMagicExtensions['wikicodeToHtml'] = ['MAG_CUSTOM', 'custom'];

Within LocalSettings.php

Magic words and their handling parser functions can be defined entirely in LocalSettings.php.

$wgHooks['ParserFirstCallInit'][] = function ( Parser $parser ) 
{
	MediaWiki\MediaWikiServices::getInstance()->getContentLanguage()->mMagicExtensions['wikicodeToHtml'] = ['wikicodeToHtml', 'wikicodeToHtml'];

	$parser->setFunctionHook( 'wikicodeToHtml', 'wikicodeToHtml' );
};
 
function wikicodeToHtml( Parser $parser, $code = '' ) 
{
	$title = $parser->getTitle();
	$options = $parser->Options();
	$options->enableLimitReport(false);
	$parser = $parser->getFreshParser();
	return [$parser->parse($code, $title, $options)->getText(), 'isHtml' => true];
}

دوال أطول

في حالات الدوال الطويلة، ربما ترغب في تقسيم دوال الربط إلى ملف ‎_body.php أو ‎.hooks.php وجعلها دوال ثابتة تحت فئة واحدة. يمكنك من ثمّ تحميل الفئة مستخدمًا ‎$wgAutoloadClasses واستدعاء الدوال الثابتة في الروابط؛ مثل:

ضع ما يلي في ملف ‎extension.json لديك:

"Hooks": {
	"ParserFirstCallInit": "ExampleExtensionHooks::onParserFirstCallInit"
},
"AutoloadClasses": {
	"ExampleExtensionHooks": "src/ExampleExtensionHooks.php"
}

ثم ضع ما يلي في ملف ‎src/ExampleExtensionHooks.php لديك:

class ExampleExtensionHooks {
      public static function onParserFirstCallInit( Parser $parser ) {
           $parser->setFunctionHook( 'example', [ self::class, 'renderExample' ] );
      }
}

الحفظ المؤقت

كما هو الحال في امتدادات الوسم، يجوز استخدام $parser->disableCache()‎ في تعطيل الحفظ المؤقت لأغراض الامتدادات التفاعلية. (متقادم في 1.28)

يحمل هذا الأمر أثرًا سلبيًا على الأداء، لذا استخدمه إن استلزم الأمر ذلك لا غير.

واجهة المعرب اللغوي

التحكم في الإعراب اللغوي للمخرجات

إن أردت أن تُعرَب نصوص الويكي التي تُرجِعها دوال المعرب اللغوي إعرابًا برمجيًا كاملًا (يشمل ذلك توسيع القوالب)، اضبط قيمة خيار noparse لتصبح «false» أثناء الرجوع:

return [ $output, 'noparse' => false ];

يبدو أن القيمة الافتراضية لخيار noparse تغيرت من «false» إلى «true»، على الأقل في بعض الحالات، في وقت ما قريب من الإصدار 1.12.

بالعكس، كي تجعل دوال المعرب اللغوي لديك ترد نص إتش تي إم إل يظل دون إعراب برمجي، بدلا من رده في صيغة نصوص ويكي، استخدم التالي:

return [ $output, 'noparse' => true, 'isHTML' => true ];


التسمية

تضيف برمجيات ميدياويكي بصفة افتراضية محرف «هاش» (علامة الرقم، «#») إلى اسم كل دالة من دوال المعرب اللغوي. كي توقف هذه الإضافة (والحصول على دوال معرب لغوي لا يضاف إليها البادئة «#»)، أضف الثابت ‎SFH_NO_HASH‎ في وسيطة الوسوم الاختيارية إلى setFunctionHook، كما هو مبين فيما يلي.

حينما تختار اسم لا يحتوي على البادئة «هاش»، لاحظ أن ضم صفحة تحمل اسم يبدأ باسم تلك الدالة يتبعه علامة النقطتين لن يصبح ممكنًا. تجنب على وجه التحديد أسماء الدوال التي تساوي اسم نطاق اسم. في حالة أن ضم [١] بين مواقع الويكي مفعّل، تجنب أيضًا أسماء الدوال التي تساوي بادئة وصل بين مواقع الويكي.

الرابط setFunctionHook

لمزيد من التفاصيل عن الواجهة في المعرب اللغوي، طالع توثيق رابط setFunctionHook في ملف ‎includes/Parser.php‎. إليك نسخة (يحتمل أن تكون متقادمة) من تلك التعليقات:

function setFunctionHook( $id, $callback, $flags = 0 ) Parameters:

  • ‎$id النص – معرف الكلمة السحرية
  • ‎$callback مختلط – دالة الاستدعاء (والعنصر) المطلوب استخدامها
  • ‎$flags الأعداد الصحيحة – اختياري، ضبطت قيمته لتكون ثابت ‎SFH_NO_HASH‎ كي تستدعي الدالة دون استخدام «#».

القيمة المردودة: دالة الاستدعاء القديمة لهذا الاسم، في حال وجودها

صغ دالة، مثل، ‎{{#sum:1|2|3}}‎. يجب أن تكون دالة الاستدعاء على الشكل التالي:

function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }

يجوز أن يرد الاستدعاء إما النتيجة النصية للدالة أو متوالية يوجد النص فيها في العنصر «0» وعدد من الوسوم في العناصر الأخرى. تحدد أسماء الوسوم في المفاتيح. الوسوم الصالحة كما يلي:

forceRawInterwiki
أجبر حالات الدمج بين مواقع الويكي أن تجري في الوضع الخام، لا في وضع يعرض النتيجة النهائية.
found
النص المردود صالح، أوقف معالجة القالب. هذا الخيار مفعّل بصفة افتراضية.
isChildObj
النص هو عنقود DOM يحتاج للتوسيع في إطار تابع.
isHTML
النص المردود هو نص إتش تي إم إل، احفظه من أن يتغير إلى نصوص ويكي. But see discussion
isLocalObj
النص هو عنقود DOM يحتاج للتوسيع في الإطار الحالي.
noparse
يجب نزع وسوم إتش تي إم إل غير الآمنة، وخلافه
nowiki
يجب تخطي ترميز الويكي الموجود في القيمة المردودة.
preprocessFlags
استخدم هذه الوسوم حينما تعرب النص المردود برمجيًا. ينطبق هذا حينما يكون noparse هو false لا غير.
text
النص المردود من السمة. لو كانت isChildObj أو isLocalObj محددة، ينبغي أن يكون هذا عنقود DOM بدلا من ذلك.
title
عنصر Title حيث أخذ النص.

متغيرات تحمل اسم

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

function ExampleExtensionRenderParserFunction( &$parser ) {
	// Suppose the user invoked the parser function like so:
	// {{#myparserfunction: foo=bar | apple=orange | banana }}

	$options = extractOptions( array_slice( func_get_args(), 1 ) );

	// Now you've got an array that looks like this:
	// [foo] => 'bar'
	// [apple] => 'orange'
	// [banana] => true
	// Continue writing your code...
}

/**
 * Converts an array of values in form [0] => "name=value"
 * into a real associative array in form [name] => value
 * If no = is provided, true is assumed like this: [name] => true
 *
 * @param array string $options
 * @return array $results
 */
function extractOptions( array $options ) {
	$results = [];
	foreach ( $options as $option ) {
		$pair = array_map( 'trim', explode( '=', $option, 2 ) );
		if ( count( $pair ) === 2 ) {
			$results[ $pair[0] ] = $pair[1];
		}
		if ( count( $pair ) === 1 ) {
			$results[ $pair[0] ] = true;
		}
	}
	return $results;
}

انظر أيضا