אונטערשייד צווישן ווערסיעס פון "מעדיעוויקי שמועס:Gadget-TemplateParamWizard"

פון המכלול
קפיצה לניווט קפיצה לחיפוש
אין תקציר עריכה
צייכן: צוריקגעשטעלט
ק (טעות)
צייכן: צוריקדריי
שורה 1: שורה 1:
//Template parameters wizard
[[קובץ:TemplatesWizard.png|250px|ממוזער|דוגמה לשימוש באשף תבניות עם ה[[המכלול:תבנית|תבנית]] "{{תב|מדען}}". לאחר בחירת תבנית, ייפתח [[טופס]] למילוי תבנית כמוצג.]]
//Written by [[User:קיפודנחש]]
'''אשף התבניות''' (לא "אשף תבניות קישורים"), מאפשר הוספה ומילוי של [[המכלול:תבנית|תבניות]] קיימות היישר מ[[הילף:רעדאגירן א בלאט|דף העריכה]], בקלות ובמהירות. האשף הכללי עובד בצורה חלקית. אשף התבניות עובד באופן שלם, רק כאשר יש לתבנית מבוקשת templatedata (ראו בהמשך).
"use strict";
if(($.inArray(mw.config.get('wgAction'), ['edit', 'submit'])+1) && ( !$('#wpTextbox1').prop( 'readonly' ) ) )
$(function($) {
// template parameter is an object with the following fields:
// desc: desciption string
// defval: default value (optional)
// options: object with optional fields:
//// multiline: number of lines
//// depends: another field's name
//// required: boolean
//// date: use JS date widget
//// choices: array of legal values for the field
//// extended: this field will not show on initial screen, and will appear once the user selects "show all fields"


var
אשף התבניות בעורך קוד מקור פועל בצורה דומה לאשף המקביל בעורך החזותי. בעורך החזותי מפעילים את האשף על ידי הקשה על התבנית, ואז "עריכה", או, כדי להוסיף תבנית חדשה, הקשה על "הוספה" בתפריט העליון, ובחירה ב"תבנית".
// templateParams is keyed by paramName.
templateParams,
paramsOrder,
// which template are we working on
template,
// array of pairs - [paramName, inputField]
dialogFields,
// table rows keyed by paramName
rowsBypName,
// the fields, keyed by paramName
fieldsBypName,
// boolean, indicating the source of data is templatedata.
tdTemplate,
// boolean, indicating the source of the data is analyzing the template page itself.
rawTemplate,
isInline,
rtl = $('body').is('.rtl'),
// test to see if a string contains wikiCode and hence needs parsing, or cen be used as is.
wikiCodeFinder = /[\[\]\{\}<>]/,
globalExplanation = '',
extendedParamCssRule,
anyExtended = false,
localStorageKey = 'templateParamWizard',
emptiesKey = 'writeEmpties',
oneLineTemplate = 'oneLineTemplate',
allAliases = [];


function addParam(name) {
==התקנת האשף==
if ($.inArray(name, paramsOrder) == -1)
בראש הדף, תחת "העדפות" ← "[[הילף:טשאטשקעס|גאדג'טים]]" ([[באַזונדער:העדפות#mw-prefsection-gadgets]]), יש לבחור "{{מדיה ויקי:Gadget-TemplateParamWizard}}". שימו לב, שהבחירה הזו מאופשרת כ[[ברירת מחדל]].
paramsOrder.push(name);
}


function paramsFromSelection() {
אם הוספתם את השורה הבאה ל[[באַזונדער:הדף שלי/common.js]], אנא הסירו אותה:
var selection = $("#wpTextbox1").textSelection('getSelection').replace(/^\s*\{\{|\}\}\s*$/g, ''); //scrap the first {{ and last }}
<syntaxhighlight lang="javascript">
var specials = [],
importScript('mediawiki:TemplateParamWizard.js');
match;
</syntaxhighlight>
while (true) { //extract inner links, inner templates and inner params - we don't want to split those.
match = selection.match(/(\{\{[^\{\}\]\[]*\}\}|\[\[[^\{\}\]\[]*\]\]|\[[^\{\}\]\[]*\])/);
if (! match || ! match.length)
break;
specials.push(match[0]);
selection = selection.replace(match[0], "\0" + specials.length + "\0");
}
var params = selection.split(/ *\| */);
params.shift(); // remove the template name
var ordered = 0;
for (var i in params) {
var param = params[i];
if ( ! /=/.test(param) ) {
param = ++ordered + '=' + param;
}
var paramPair = param.split("=");
var name = $.trim(paramPair.shift());
if ( ! isNaN( name ) ) {
ordered = parseInt( name ); // this still won't work as advertise when template contains explicit parameter 2 before implicit 1: {{x | 2 = hey | ho }}
}
var val = paramPair.join('=');
while (true) {
match = val.match(/\0(\d+)\0/);
if (! match || ! match.length)
break;
val = val.replace(match[0], specials[parseInt(match[1], 10)-1]);
}
if (name && paramPair.length) {
var tp = templateParams[name] =
templateParams[name] ||
~allAliases.indexOf(name) && { param:{}, options: {isAlias: 1} } ||
{param: {}, options: { notInParamPage: 1}};
addParam(name);
$.extend( tp.options, { defval: val } );
if ( /\n/.test( val ) ) $.extend( tp.options, { multiline : 5 } );
// next line is for the case where there are "choices"' but current value is not one of them: add it as a new choice.
if ( typeof tp.options.choices === 'string' && tp.options.choices.indexOf( val ) < 0 )
tp.options.choices += ( ', ' + val );
}
}
}


function buildParamsRaw(data) {
==הוראות שימוש==
var
קיימות שתי דרכים להשתמש במוסטער:
paramExtractor = /{{3,}(.*?)[<|}]/mg,
# '''יצירת''' תבנית חדשה בעת עריכת ערך.
m;
# '''עדכון''' תבנית על בסיס תבנית קיימת בעת עריכת ערך.
while (m = paramExtractor.exec(data)) {
var paramName = $.trim(m[1]);
templateParams[paramName] = { desc: '', options: {multiline: 5}, label: paramName, param:{} };
addParam(paramName);
}
}
function buildParamsTd(data) {
var params = data.params,
paramOrder = data.paramOrder;


function optionsOfParam(param) {
===יצירת תבנית חדשה===
var options = {};
בכדי ליצור תבנית חדשה, יש ללחוץ על הכפתור [[קובץ:Vector toolbar template button.png]] כאשר נמצאים במצב עריכה. האשף יפתח חלון, שמאפשר להזין את שם התבנית הרצויה מתוך רשימה. לאחר לחיצה על "אישור", תגיעו לאשף עצמו.
if (param.required) options.required = true;
if (param.suggestedvalues && param.suggestedvalues.length) options.choices = param.suggestedvalues.join(',');
return options;
}


function onemore(name) {
ניתן גם לרשום את שם התבנית בערך באופן הבא <nowiki>{{שם תבנית}}</nowiki>, ואז לסמן את התבנית וללחוץ על הכפתור [[קובץ:Vector toolbar template button.png]]. האשף מייצר ומציג טופס עם שם הפרמטר, ותיבת הכנסת טקסט ([[שדה (אחסון נתונים)|שדה מילוי]]).
var param = params[name];
if (param.deprecated)
return; // ignore deprecated parameters - pretend they are not in TD.
templateParams[name] = {
desc: param.description || '',
options: optionsOfParam(param),
label: param.label || name,
param: param
};
if (param.aliases) $.merge(allAliases, param.aliases); // collect alliases if there are any
addParam(name);
}
isInline = data.format === 'inline';
if (paramOrder && paramOrder.length)  
for (var ind in paramOrder)
onemore(paramOrder[ind]);
else // no order - take them as they come.
for (var paramname in params)
onemore(paramname);


// derive placeholders for feilds derived from wikidata
===עדכון תבנית קיימת===
if (data.maps && data.maps.hasOwnProperty('wikidata') && mw.config.get('wgWikibaseItemId')) {
ניתן להשתמש באשף גם לתיקונים קטנים (או גדולים) בתבנית קיימת, שכבר מולאה באופן חלקי. לשם כך, יש לסמן את התבנית הקיימת בערך וללחוץ על כפתור [[קובץ:Vector toolbar template button.png]]. האשף יקרא את הנתונים מהערך עצמו.
var wikidataFormattedValues = $('<div>');
for (var k in data.maps['wikidata']) {
wikidataFormattedValues.append($('<span>', {id: k, text:'{{#property:' + k + '}}'}))
}
$.post(
mw.util.wikiScript('api'),
{action: 'parse', text: wikidataFormattedValues.html(), disablelimitreport: 1, format: 'json', prop: 'text', title: mw.config.get('wgPageName')},
function(wbd) {
if (!wbd || !wbd.parse || !wbd.parse.text) return;
for (var k in data.maps['wikidata']) {
var wikidataVal = $('#' + k, wbd.parse.text['*']).text(),
field = fieldsBypName[data.maps['wikidata'][k]];
if (field)
field.prop('placeholder', wikidataVal);
}
}
);
}
}


function buildParams(data) {
'''שימו לב''', שיש לסמן את התבנית כולה, כולל הפרמטרים שכבר קיימים. האשף יאסוף את הערכים הללו מהדף וימלא את השדות המתאימים.
var
lines = data.split("\n"),
line;


function extractGlobalExplanation() {
בזמן עריכה, אם מאופשר אצלכם ה[[הילף:טשאטשקעס|גאדג'ט]] של autocomplete, הוא יעבוד גם על השדות באשף; כלומר, כאשר תוסיפו <code><nowiki>[[</nowiki></code> לאחד השדות באשף ותתחילו להקיש שם ערך, האשף יציע ערכים מתאימים לתווים שכבר הקשתם, בדומה ל[[המכלול:ניווט|תיבת החיפוש]].
line = line.replace(/[!\|][^\|]*\|/, '');
if (wikiCodeFinder.test(line))
$.post(
mw.util.wikiScript('api'),
{action: 'parse', text: line, disablepp: 1, format: 'json'},
function(data) {
var html = data.parse.text['*'];
globalExplanation = html;
$('#tpw_globalExplanation').html(html).find('a').attr({target: '_blank'});
}
);
else
globalExplanation = line;
}


while (lines && lines.length) {
== templatedata ==
line = lines.shift();
כאשר יש לתבנית tempaltedata, האשף ישתמש בה לרשימת הפרמטרים, תיאור כל פרמטר, החלטה מתי פרמטר מסוים הוא "חובה", והחלטה האם לסדר תבנית בשורה אחת או שורה לכל פרמטר. אם אין tempaltedata, האשף מנסה למצות את רשימת הפרמטרים על ידי ניתוח דף התבנית, פעולה שהצלחתה אינה מובטחת. אם רשימת הפרמטרים שהאשף מציע אינה נכונה, יש ליצור tempaltedata בתבנית, או לתקן את הקיים.
if (!(/^\|-/.test(line))) // look for |- this is wikitext for table row.
continue;
line = lines.shift();
if (line.indexOf('globalExplanation') + 1) {
extractGlobalExplanation();
continue;
}
if (! line || ! (/^\|/.test(line))) //wikitext for column
continue;
line = line.substr(1); // get rid of the leading |
var fields = line.split('||');
if (fields.length < 2)
continue;
var name = $.trim(fields[0]);
if (! name)
continue;
var desc = $.trim(fields[1]);
var pAttribs = {desc: desc};
if (fields.length > 2)
pAttribs.options = analyzeOptions($.trim(fields[2]));


templateParams[name] = pAttribs;
מידע נוסף על tempaltedata ניתן למצוא ב[[mw:Help:TemplateData/he]].
addParam(name);


}
==ראו גם==
}
* [[המכלול:תבנית]]
* [[הילף:מוסטערן]]


function analyzeOptions(str) {
[[קאטעגאריע:המכלול טעכנישע הילף]]
var res = {},
avail = ['multiline', 'required', 'depends', 'defval', 'choices', 'date', 'extended'], // maybe we'll have more in the future
tavail = $.map(avail, i18n),
options = str.split(/\s*;\s*/);
for (var i in options) {
var option = options[i].split(/\s*=\s*/);
var ind = $.inArray(option[0], tavail);
if (ind + 1)
res[avail[ind]] = option.length > 1 ? option[1] : true;
}
anyExtended = anyExtended || res.extended;
return res;
}
 
function createWikiCode() {
var par = [template],
delim = $('#' + oneLineTemplate).prop('checked') ? '' : '\n',
paramValueDelim =  $('#' + oneLineTemplate).prop('checked') ? '=' : ' = ',
createEmpties = $('#createEmpties').prop('checked'),
mustNumberNameless,
valuedOrdered;
for (var i = dialogFields.length - 1; i >= 0; i--) {
var field = dialogFields[i],
val = $.trim(field[1].val());
if (isNaN(field[0])) continue; // look only at order-based fields
mustNumberNameless |=
/=/.test(val) // order-based value containing "="
|| valuedOrdered && !val; // empty ordered w lower index than a non-empty one.
if (val) valuedOrdered = true;
}
for (var i in dialogFields) {
var
field = dialogFields[i],
name = $.trim(field[0]),
f = field[1],
opts = f.data('options'),
param = templateParams[name],
hidden = f.parents('.tpw_hidden').length,
val = f.val().replace( /\s+$/, '' ); // leave leading newlines, for lists etc., but remove trailing.
if (param && param.param && param.param.type === 'url')
val = val.replace(/\|/g, '{{!}}');
if (f.attr('type') == 'checkbox' && ! f.prop('checked'))
val = "";
if ( ( !createEmpties || opts.notInParamPage )  && $.trim( val ) === "" )
continue;//skip parameters with no value
var next = mustNumberNameless || isNaN(name)
? name + paramValueDelim + $.trim( val )
: $.trim( val );
par.push(next);
}
return "{{" + par.join(delim + ($('#' + oneLineTemplate).prop('checked')? "|" : "| ")) + delim + "}}";
}
 
function showPreview() {
var temp = createWikiCode();
$.post(mw.util.wikiScript('api'),
{action: 'parse',
title: mw.config.get('wgPageName'),
prop: 'text',
text: temp,
format: 'json'
},
function(data) {
if (data && data.parse && data.parse.text) {
var buttons = [{text: i18n('close'), click: function() {$(this).dialog('close');}}],
div = $('<div>').html(data.parse.text['*']);
$('a', div).attr('target', '_blank'); // we don't want people to click on links in preview - they'll lose their work.
$('<div>')
.dialog(
{title: i18n('preview'),
modal: true,
position: [60, 60],
buttons: buttons})
.append(div);
circumventRtlBug();
}
});
}
 
function circumventRtlBug() {
if (rtl)
$('.ui-dialog-buttonpane button').css({float: 'right'}); // jQuery has problems with rtl dialogs + ie is braindamaged.
}
 
function i18n(key, param) {
switch (mw.config.get('wgUserLanguage')) {
case 'ar':
switch (key) {
case 'explain': return rawTemplate
? 'قالب "' + template + '" ليس له صفحة وسائط فرعية، لذلك فما من وصف لمعطياته.'
: 'الوسائط الضرورية محددة بالأحمر والبقية اختيارية.';
case 'wizard dialog title': return 'وسائط ' + '<a href="' + mw.util.getUrl('قالب:' + template) + '" target="_blank">' + 'قالب:' + template + '</a>';
case 'ok': return 'موافقة';
case 'cancel': return 'إلغاء';
case 'params subpage': return 'وسائط';
case 'preview': return 'معاينة';
case 'options select': return 'اختر معطى';
case 'multiline': return 'عدد صفوف';
case 'close': return 'أغلق';
case 'required': return 'ضروري';
case 'depends': return 'يلزمه';
case 'defval': return 'غيابي';
case 'choices': return 'خيارات';
case 'date': return 'تاريخ';
case 'extended': return 'مفصل';
case 'button hint': return 'معالج وسائط القالب';
case 'template selector title': return 'اكتب اسم القالب:';
case 'notInParamPage': return 'وسيط "' + param + '" ليس من وسائط القالب';
case 'editParamPage': return 'عدل صفحة الوسائط';
case 'unknown error': return 'وقع خطأ.\n' + param;
case 'please select template': return 'اسم القالب';
case 'oneliner': return 'اجعله في صف واحد';
case 'createempties': return 'إضافة الوسائط فارغة';
case 'dateFormat': return 'd MM yy';
case 'extended labels': return 'عرض كل الوسائط';
default: return key;
}
break;
case 'he':
switch (key) {
case 'explain': return hebExplain();
case 'wizard dialog title': return 'מילוי הפרמטרים עבור ' + '<a href="' + mw.util.getUrl('תבנית:' + template) + '" target="_blank">' + 'תבנית:' + template + '</a>';
case 'ok': return 'אישור';
case 'cancel': return 'ביטול';
case 'preview': return 'תצוגה מקדימה';
case 'options select': return 'בחרו ערך מהרשימה';
case 'multiline': return 'מספר שורות';
case 'close': return 'סגור';
case 'required': return 'שדה חובה';
case 'depends': return 'תלוי';
case 'defval': return 'ברירת מחדל';
case 'choices': return 'אפשרויות';
case 'date': return 'תאריך';
case 'extended': return 'משני';
case 'button hint': return 'אשף מילוי תבניות';
case 'template selector title': return 'אנא הזינו את שם התבנית:';
case 'notInParamPage': return 'השדה "' + param + '" לא מופיע ברשימת הפרמטרים של התבנית';
case 'editParamPage': return 'לעריכת דף הפרמטרים';
case 'unknown error': return 'טעות בהפעלת האשף.\n' + param;
case 'please select template': return 'שם התבנית';
case 'oneliner': return 'תבנית בשורה אחת';
case 'createempties': return 'רשום שדות ריקים';
case 'dateFormat': return 'd בMM yy';
case 'extended labels': return 'הראה את כל הפרמטרים';
case 'pve-required-empty': return 'התבנית דורשת שפרמטר זה יקבל ערך';
case 'pve-deprecated': return 'שימוש בפרמטר מיושן';
case 'pve-incompatible': return 'שדה זה מצפה לערך מספרי';
case 'pve-no-such-name': return 'שדה זה לא קיים בתבנית';
case 'explain-pve': return 'שדות עם שגיאה מסומנים ברקע ורוד';
case 'pve-approve-close': return 'יש בתבנית שגיאות. אנא אשרו יציאה מהאשף';
}
break;
case 'ur':
switch (key) {
case 'explain': return 'جو خانے لازمی ہیں ان کے گرد سرخ رنگ کی لکیر کھینچ دی گئی ہے، بقیہ خانے اختیاری ہوں گے۔';
case 'wizard dialog title': return 'سانچہ: "' + template + '" میں مطلوبہ معلومات درج کریں۔';
case 'ok': return 'ٹھیک';
case 'cancel': return 'منسوخ کریں';
case 'params subpage': return 'پیرامیٹر';
case 'preview': return 'نمائش';
case 'options select': return 'کسی ایک کو منتخب کریں:';
case 'multiline': return 'سطروں کی تعداد';
case 'close': return 'بند کریں';
case 'required': return 'لازمی';
case 'depends': return 'اس پر موقوف ہے';
case 'defval': return 'طے شدہ';
case 'choices': return 'اختیارات';
case 'date': return 'تاریخ';
case 'extended': return 'مفصل';
case 'button hint': return 'ساحر محددات سانچہ';
case 'template selector title': return 'براہ کرم سانچہ کا نام درج کریں';
case 'notInParamPage': return 'پیرامیٹر کی فہرست میں "' + param + '" ظاہر نہیں ہو رہا ہے';
case 'editParamPage': return 'پیرامیٹر کے صفحہ میں ترمیم کریں';
case 'unknown error': return 'نقص پیش آیا: \n' + param;
case 'please select template': return 'براہ کرم سانچہ کا نام درج کریں';
case 'oneliner': return 'یک سطری';
case 'createempties': return 'صفحہ میں خالی پیرامیٹر درج کریں';
case 'dateFormat': return 'd MM yy';
case 'extended labels': return 'تمام پیرامیٹر دکھائیں';
}
break;
case 'ru':
switch (key) {
case 'explain': return 'поля с красной рамкой обязательны, остальные - по желанию';
case 'wizard dialog title': return 'Настройте параметры для шаблона: ' + template;
case 'ok': return 'OK';
case 'cancel': return 'Отмена';
case 'params subpage': return 'Параметры';
case 'preview': return 'Просмотр';
case 'options select': return 'Выбрать:';
case 'multiline': return 'Многострочный вид';
case 'close': return 'Закрыть';
case 'required': return 'Необходимое';
case 'depends': return 'Зависит от';
case 'defval': return 'По умолчанию';
case 'choices': return 'Выбор';
case 'date': return 'Дата';
case 'extended': return 'Расширенный';
case 'button hint': return 'Мастер параметров шаблона';
case 'able templates category name': throw('Необходимо определить название категории для шаблонов с поддержкой мастера');
case 'template selector title': return 'Пожалуйста, введите имя шаблона';
case 'notInParamPage': return 'поле "' + param + '" не отображается в списке параметров шаблона';
case 'editParamPage': return 'Править страницу параметров';
case 'unknown error': return 'Произошла ошибка: \n' + param;
case 'please select template': return 'Пожалуйста, введите имя шаблона';
case 'oneliner': return 'Однострочный вид';
case 'dateFormat': return 'ММ дд, гг';
case 'extended labels': return 'Показать все параметры';
}
default:
switch (key) {
case 'explain': return 'fields with red border are required, the rest are optional';
case 'wizard dialog title': return 'Set up parameters for template: ' + template;
case 'ok': return 'OK';
case 'cancel': return 'Cancel';
case 'params subpage': return 'Parameters';
case 'preview': return 'Preview';
case 'options select': return 'Select one:';
case 'multiline': return 'Multiline';
case 'close': return 'Close';
case 'required': return 'Required';
case 'depends': return 'Depends on';
case 'defval': return 'Default';
case 'choices': return 'Choices';
case 'date': return 'Date';
case 'extended': return 'Extended';
case 'button hint': return 'Template parameters wizard';
case 'template selector title': return 'Please enter the template name';
case 'notInParamPage': return 'field "' + param + '" does not appear in the template\'s parameters list';
case 'editParamPage': return 'Edit paramters page';
case 'unknown error': return 'Error occured: \n' + param;
case 'please select template': return 'Please enter template name';
case 'oneliner': return 'Single-line template';
case 'createempties': return 'Write empty parameters to page';
case 'dateFormat': return 'MM d, yy';
case 'extended labels': return 'Show all parameters';
case 'pve-required-empty': return 'The template requires a value for this filedך';
case 'pve-deprecated': return 'deprecated parameter';
case 'pve-incompatible': return 'expaects numteric value';
case 'pve-no-such-name': return 'undercgonzed parameter';
case 'explain-pve': return 'fields with errors are marked with pink background';
case 'pve-approve-close': return 'Template contains errors. Please confim exit';
}
}
return key;
}
 
function hebExplain() {
var explanation;
if (rawTemplate) return 'לתבנית "' + template + '" אין דף פרמטרים, ולכן לשדות אין תיאור.';
if (anyRequiredParam()) return 'שדות חובה מסומנים במסגרת אדומה';
return '';
}
function anyRequiredParam() {
for (name in templateParams) {
var param = templateParams[name];
if (param.options.required) return true;
}
return false;
}
function templatePage() {
var t = $.trim(template)
return t.match(':') ? t : mw.config.get('wgFormattedNamespaces')[10] + ':' + t;
}
 
function updateRawPreview(){
var canOK = 'enable';
for (var i in dialogFields) {
var df = dialogFields[i][1];
var opts = df.data('options');
if (opts && opts.required && $.trim(df.val()).length == 0)
canOK = 'disable';
if (opts && opts.depends) {
var dep = fieldsBypName[opts.depends];
var depEmpty = (dep && dep.val() && $.trim(dep.val())) ? false : true;
var row = rowsBypName[df.data('paramName')];
if (row)
row.toggleClass('tpw_hidden', depEmpty);
}
}
$(".ui-dialog-buttonpane button:contains('" + i18n('ok') + "')").button(canOK);
$('#tpw_preview').text(createWikiCode());
localStorage.setItem(localStorageKey + '.' + emptiesKey, $('#createEmpties').prop('checked'));
validate();
}
function validate() {
function validateField(param, input) {
function markError(msg) {
input
.addClass('tpw-paramvalidation')
.attr('title', i18n(msg));
return false;
}
var hasVal = !! input.val();
if (param.options.notInParamPage && hasVal) return markError('pve-no-such-name');
if (param.param.required && ! hasVal) return markError('pve-required-empty');
if (param.param.deprecated && hasVal) return markError('pve-deprecated');
if (param.param.type === 'number' && isNaN( Number( input.val().replace(/,/g, '') ) ) ) return markError('pve-incompatible');
return true;
}
var aOK = true;
for (var i in dialogFields) {
var
field = dialogFields[i],
name = $.trim(field[0]),
input = field[1].removeClass('tpw-paramvalidation'),
param = templateParams[name];
aOK = validateField(param, input) && aOK;
}
$('#tpw-explain').html(i18n(aOK ? 'explain' : 'explain-pve') );
return aOK;
}
 
function createInputField(paramName) {
var params = templateParams[paramName],
options = params.options || {},
f,
checkbox = false;
 
if (options.choices) {
var choices = options.choices.split(/\s*,\s*/);
if (choices.length > 1) {
f = $('<select>').append($('<option>', {text: i18n('options select'), value: '' }));
for (var i in choices) {
var choice = choices[i].trim(); // first and last may carry spaces
var option = $('<option>', {text: choice, value: choice});
f.append(option);
}
}
else {
checkbox = true;
var choice = choices[0].trim();
f = $('<input>', {type: 'checkbox', value: choices[0], text: choices[0].trim()})
.css({float: rtl ? 'right' : 'left'});
f.prop('checked', options.defval && options.defval.trim() == choices[0]);
}
}
else if (options.multiline) {
var rows = options.multiline;
f = $('<textarea>', {rows: 1})
.focus(function(){this.rows = 5;})
.blur(function(){this.rows = 1});
}
else
f = $('<input>', {type: 'text'});
 
if (!checkbox && f.autoCompleteWikiText) // teach the controls to autocomplete.
f.autoCompleteWikiText({positionMy: rtl ? "left top" : "right top"});
 
f.css({width: checkbox ? '1em' : '28em'})
.data({paramName: paramName, options: options})
.on('paste cut drop input change', updateRawPreview);
 
if (options.defval && ! checkbox)
f.val(options.defval.trim());
 
if (options.required)
f.addClass('tpw-required');
 
if (options.date)
f.datepicker({dateFormat: typeof options.date  == "string" ? options.date : i18n('dateFormat')});
return f;
}
 
var
timer = null,
lastVisited = $('<a>');
 
function enterTipsy() {
clearTimeout(timer);
$(this).attr('inside', 1);
}
 
function leaveTipsy() {
var $this = $(this);
if ($this.attr('master') || $this.attr('inside')) {
$this.attr('inside', '');
timer = setTimeout(function(){lastVisited.tipsy('hide');}, 500);
}
}
 
function tipsyContent() {
var
paramName = $(this).data('paramname'),
def = templateParams[paramName],
desc = def && def.desc || '';
if (!def) return ''; // early terminate if param name is not valid
if (def.htmlDesc)
return def.htmlDesc;
if (wikiCodeFinder.test(desc)) // does it need parsing?
$.ajax({
url: mw.util.wikiScript('api'),
async: false,
type: 'post',
data: {action: 'parse', text: desc, disablepp: 1, format: 'json'}, // parse it.
success: function(data) {
var div = $('<div>').html(data.parse.text['*']);
$('a', div).attr({target: '_blank'});
def.htmlDesc = div.html();
}
});
else
def.htmlDesc = desc;
return def.htmlDesc;
}
 
function addRow(paramName, table) {
var
def = templateParams[paramName],
inputField = createInputField(paramName),
nameColor = def.desc
? 'blue'
: def.options.notInParamPage
? 'red'
: def.options.isAlias
? 'green'
: 'black',
tr = $('<tr>')
.append(
$('<td>', {width: 120})
.css({fontWeight: 'bold', color: nameColor})
.data({ paramname: paramName })
.text(templateParams[paramName].label || paramName)
.tipsy({html: true, trigger: 'manual', title: tipsyContent})
.mouseenter(function() {
clearTimeout(timer);
$('.tipsy').remove();
lastVisited = $(this);
lastVisited.tipsy('show');
})
.mouseleave(leaveTipsy)
.attr('master', 'true')
)
.append($('<td>').css({width: '30em'}).append(inputField));
dialogFields.push([paramName, inputField]);
if (def.options.extended)
tr.addClass('tpw_extended');
table.append(tr);
rowsBypName[paramName] = tr;
fieldsBypName[paramName] = inputField;
}
 
function injectResults() {
$("#wpTextbox1").textSelection('encapsulateSelection', {replace: true, peri: createWikiCode()});
}
 
function createExtendedCheckBox() {
return $('<p>')
.text(i18n('extended labels'))
.append($('<input>', {type: 'checkbox'})
.change(function() {
extendedParamCssRule.disabled = $(this).prop('checked');
})
);
}
 
function buildDialog(data) {
var title = $('<span>').html(i18n('wizard dialog title', template));
$('.tpw_disposable').remove();
if (rawTemplate)
buildParamsRaw(data);
else if (tdTemplate) {
buildParamsTd(data);
if (data.description) title.find('a').attr({ title: data.description });
}
paramsFromSelection();
var table = $('<table>');
var dialog = $('<div>', {'class': 'tpw_disposable'})
.dialog({height: 'auto',
title: title.html(),
width: 'auto',
overflow: 'auto',
position: [$('body').width() * 0.2, $('body').height() * 0.1],
open: function() {$(this).css({'max-height': Math.round($('body').height() * 0.7)});}
})
.append($('<div>', {id: 'tpw_globalExplanation'}).html(globalExplanation))
.append($('<p>', { id: 'tpw-explain' } ).html(i18n('explain')) )
.append(anyExtended ? createExtendedCheckBox() : '')
.append(table)
.append($('<p>')
.append(i18n('oneliner'))
.append($('<input>', {type: 'checkbox', id: oneLineTemplate}).prop('checked', isInline).change(updateRawPreview)
)
)
.append($('<p>')
.append(i18n('createempties'))
.append($('<input>', {type:'checkbox', id:'createEmpties'})
.change(updateRawPreview)
.prop('checked', localStorage.getItem(localStorageKey + '.' + emptiesKey) == "true")
)
)
.append($('<pre>', {id: 'tpw_preview'}).addClass('tpw-wikicode-preview'));
while (paramsOrder.length)
addRow(paramsOrder.shift(), table);
 
var buttons = {}; // we need to do it this way, because with literal object, the keys must be literal.
buttons[i18n('ok')] = function() {
if (! validate() && ! confirm(i18n('pve-approve-close' ) ) ) return;
injectResults();
dialog.dialog('close');
};
buttons[i18n('cancel')] = function() {dialog.dialog('close');};
buttons[i18n('preview')] = showPreview;
dialog.dialog('option', 'buttons', buttons);
circumventRtlBug();
updateRawPreview();
$('.tipsy').hover(enterTipsy, leaveTipsy);
}
 
function init() {
template = null;
templateParams = {};
paramsOrder = [];
dialogFields = [];
rowsBypName = {};
fieldsBypName = {};
mw.util.addCSS(".tpw_hidden{display:none;}");
anyExtended = false;
extendedParamCssRule = extendedParamCssRule || mw.util.addCSS(".tpw_extended{display:none;}");
}
 
function reportError(a,b,error) {
var key;
if (typeof console != 'undefined') {
for (key in a)
if (typeof a[key] != 'function')
console.log(key + '=>' + a[key]);
console.log(b);
console.log(error);
}
alert(i18n('unknown error', error));
}
 
function pickTemplate(item) {
function okButtonPressed(e, ui) {
template = ui ? ui.item.value : selector.val();
fireDialog();
templateSelector.dialog("close");
}
var selector = $('<input>')
.css({width: '28em'})
.autocomplete({
source: function(request, response) {
$.getJSON(
mw.util.wikiScript('api'),
{action:'opensearch', search: request.term, namespace: 10},
function(data){
if(data[1])
response($(data[1]).map(function(index,item){return item.replace(/.*:/, '');}));
}
);
},
select: okButtonPressed
});
var templateSelector = $('<div>').dialog({
title: i18n('template selector title'),
height: 'auto',
width: 'auto',
modal: true,
buttons: [
{text: i18n('ok'), click: okButtonPressed},
{text: i18n('cancel'), click: function(){templateSelector.dialog("close")}}
]
}).append(selector);
circumventRtlBug();
selector.focus();
}
 
function fireDialog() {
var readRaw = function() {
rawTemplate = true;
$.ajax({
url: mw.util.wikiScript(),
data: {title: templatePage(), action: 'raw'},
dataType: 'text',
success: buildDialog,
error: reportError
});
},
readTemplateData = function() {
$.ajax({
url: mw.util.wikiScript('api'),
data: {action: 'templatedata', titles: templatePage(), redirects: true, format: 'json', lang: mw.config.get('wgUserLanguage') },
dataType: 'json',
success: function(data) {
var found = false;
if (data && data.pages)
for (var pageid in data.pages) {
tdTemplate = true;
found = true;
buildDialog(data.pages[pageid]);
break;
}
if (! found)
readRaw();
},
error: readRaw
});
};
rawTemplate = false;
readTemplateData();
}
 
function templateContext() {
var selection = $("#wpTextbox1").textSelection('getSelection'),
caretPos, beforeText, afterText, templateStart, templateEnd;
 
// trust the user
if ( selection.length > 0 ) {
return selection;
}
 
caretPos =  $("#wpTextbox1").textSelection('getCaretPosition');
beforeText = $("#wpTextbox1").val().substr(0, caretPos);
afterText = $("#wpTextbox1").val().substr(caretPos);
templateStart = beforeText.lastIndexOf('{{');
templateEnd = afterText.indexOf('}}') + 2;
 
// only under opportunistic template context assumptions
if ( $("#wpTextbox1").val().split('{').length != $("#wpTextbox1").val().split('}').length ||
  (beforeText.split('{{').length === beforeText.split('}}').length) ||
  (afterText.split('{{').length === afterText.split('}}').length) )
return '';
 
// determine the start and the end of the template context
while (beforeText.substr(templateStart).split('{{').length <= beforeText.substr(templateStart).split('}}').length)
templateStart = beforeText.lastIndexOf('{{', templateStart - 1)
 
while (afterText.substr(0, templateEnd).split('{{').length >= afterText.substr(0, templateEnd).split('}}').length)
templateEnd = afterText.indexOf('}}', templateEnd) + 2;
 
// extend the selection to the current template context
$("#wpTextbox1").focus().textSelection('setSelection', {
start: templateStart,
end: caretPos + templateEnd
});
return $("#wpTextbox1").textSelection('getSelection');
}
 
function doIt() {
mw.loader.using(['jquery.ui','jquery.tipsy','jquery.textSelection', 'mediawiki.api'], function() {
init();
var match = templateContext().match(/^\{\{([^|}]*)/);
template = match ? $.trim(match[1]) : null;
if (template)
fireDialog();
else
pickTemplate();
});
}
function addToWikiEditor(){
$('#wpTextbox1').wikiEditor('addToToolbar', {
section: 'main',
group: 'insert',
tools: {
'templateParamsWizard': {
label: i18n('button hint'),
type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Template_alt_full_black_22.svg/22px-Template_alt_full_black_22.svg.png',
action: {type: 'callback', execute: doIt}
}
}
});
}
if (mw.user.options.get('usebetatoolbar'))
mw.loader.using(['ext.wikiEditor'], function() {
if(typeof $.wikiEditor != 'undefined') {
if ($('#wikiEditor-ui-toolbar').length === 1) addToWikiEditor();//in case it loaded after toolbar initaliztion
else $( '#wpTextbox1' ).on( 'wikiEditor-toolbar-doneInitialSections', addToWikiEditor);
}
});
else
$('div #toolbar').append( // "old style"
$('<img>', {src: '//upload.wikimedia.org/wikipedia/commons/e/eb/Button_plantilla.png', title: i18n('button hint'), 'class': 'mw-toolbar-editbutton'})
.css({cursor: 'pointer'})
.click(doIt)
);
} );

רעוויזיע פון 17:11, 19 פעברואר 2023

דוגמה לשימוש באשף תבניות עם התבנית "{{מדען}}". לאחר בחירת תבנית, ייפתח טופס למילוי תבנית כמוצג.

אשף התבניות (לא "אשף תבניות קישורים"), מאפשר הוספה ומילוי של תבניות קיימות היישר מדף העריכה, בקלות ובמהירות. האשף הכללי עובד בצורה חלקית. אשף התבניות עובד באופן שלם, רק כאשר יש לתבנית מבוקשת templatedata (ראו בהמשך).

אשף התבניות בעורך קוד מקור פועל בצורה דומה לאשף המקביל בעורך החזותי. בעורך החזותי מפעילים את האשף על ידי הקשה על התבנית, ואז "עריכה", או, כדי להוסיף תבנית חדשה, הקשה על "הוספה" בתפריט העליון, ובחירה ב"תבנית".

התקנת האשף

בראש הדף, תחת "העדפות" ← "גאדג'טים" (באַזונדער:העדפות#mw-prefsection-gadgets), יש לבחור "מוסטער:מדיה ויקי:Gadget-TemplateParamWizard". שימו לב, שהבחירה הזו מאופשרת כברירת מחדל.

אם הוספתם את השורה הבאה לבאַזונדער:הדף שלי/common.js, אנא הסירו אותה:

importScript('mediawiki:TemplateParamWizard.js');

הוראות שימוש

קיימות שתי דרכים להשתמש במוסטער:

  1. יצירת תבנית חדשה בעת עריכת ערך.
  2. עדכון תבנית על בסיס תבנית קיימת בעת עריכת ערך.

יצירת תבנית חדשה

בכדי ליצור תבנית חדשה, יש ללחוץ על הכפתור Vector toolbar template button.png כאשר נמצאים במצב עריכה. האשף יפתח חלון, שמאפשר להזין את שם התבנית הרצויה מתוך רשימה. לאחר לחיצה על "אישור", תגיעו לאשף עצמו.

ניתן גם לרשום את שם התבנית בערך באופן הבא {{שם תבנית}}, ואז לסמן את התבנית וללחוץ על הכפתור Vector toolbar template button.png. האשף מייצר ומציג טופס עם שם הפרמטר, ותיבת הכנסת טקסט (שדה מילוי).

עדכון תבנית קיימת

ניתן להשתמש באשף גם לתיקונים קטנים (או גדולים) בתבנית קיימת, שכבר מולאה באופן חלקי. לשם כך, יש לסמן את התבנית הקיימת בערך וללחוץ על כפתור Vector toolbar template button.png. האשף יקרא את הנתונים מהערך עצמו.

שימו לב, שיש לסמן את התבנית כולה, כולל הפרמטרים שכבר קיימים. האשף יאסוף את הערכים הללו מהדף וימלא את השדות המתאימים.

בזמן עריכה, אם מאופשר אצלכם הגאדג'ט של autocomplete, הוא יעבוד גם על השדות באשף; כלומר, כאשר תוסיפו [[ לאחד השדות באשף ותתחילו להקיש שם ערך, האשף יציע ערכים מתאימים לתווים שכבר הקשתם, בדומה לתיבת החיפוש.

templatedata

כאשר יש לתבנית tempaltedata, האשף ישתמש בה לרשימת הפרמטרים, תיאור כל פרמטר, החלטה מתי פרמטר מסוים הוא "חובה", והחלטה האם לסדר תבנית בשורה אחת או שורה לכל פרמטר. אם אין tempaltedata, האשף מנסה למצות את רשימת הפרמטרים על ידי ניתוח דף התבנית, פעולה שהצלחתה אינה מובטחת. אם רשימת הפרמטרים שהאשף מציע אינה נכונה, יש ליצור tempaltedata בתבנית, או לתקן את הקיים.

מידע נוסף על tempaltedata ניתן למצוא בmw:Help:TemplateData/he.

ראו גם