Merge "Introduce new 'format' template property"

This commit is contained in:
jenkins-bot 2015-11-11 23:56:03 +00:00 committed by Gerrit Code Review
commit 0ca4dc4621
9 changed files with 189 additions and 5 deletions

View file

@ -97,6 +97,29 @@ Consumers that look for a `Map` SHOULD publicly document their identifier key.
Authors MUST ensure that the `maps` object contains only `Map` objects. Authors MAY include a parameter in multiple `Map` objects. Authors are NOT REQUIRED to reference each parameter in at least one `Map` object.
#### 3.1.6 `format`
* Value: `string` of either `inline` or `block`
* Default: `inline`
How the template's wikitext representation SHOULD be laid out. Authors MAY choose to use this parameter to express that a template will be better understood by other human readers of the wikitext representation if a template is in one form or the other.
If the parameter is set to `block`, Consumers SHOULD create a wikitext representation with a single newline after the template invocation and each parameter value, a single space between each pipe and its subsequent parameter key, and a space either side of the assignment separator between the parameter key and value, like so:
```
{{Foo
| bar = baz
| qux = quux
}}
```
If the parameter is set to `inline`, Consumers SHOULD create a wikitext representation with no whitespace, like so:
```
{{Foo|bar=baz|qux=quux}}
```
In the absence of the parameter being set, the system will supply `inline` as a fallback value. Authors are RECOMMENDED to set `inline` explicitly if they actively chose to use the template that way.
### 3.2 Param
* Value: `Object`

View file

@ -47,6 +47,7 @@ class TemplateDataBlob {
$tdb->data->description = null;
$tdb->data->params = new stdClass();
$tdb->data->paramOrder = array();
$tdb->data->format = 'inline';
$tdb->data->sets = array();
$tdb->data->maps = new stdClass();
}
@ -83,6 +84,7 @@ class TemplateDataBlob {
'paramOrder',
'sets',
'maps',
'format',
);
static $paramKeys = array(
@ -115,6 +117,11 @@ class TemplateDataBlob {
'wiki-template-name',
);
static $formats = array(
'block',
'inline'
);
static $typeCompatMap = array(
'string/line' => 'line',
'string/wiki-page-name' => 'wiki-page-name',
@ -146,6 +153,18 @@ class TemplateDataBlob {
$data->description = null;
}
// Root.format
if ( isset( $data->format ) ) {
if ( !in_array( $data->format, $formats ) ) {
return Status::newFatal(
'templatedata-invalid-format',
'format'
);
}
} else {
$data->format = 'inline';
}
// Root.params
if ( !isset( $data->params ) ) {
return Status::newFatal( 'templatedata-invalid-missing', 'params', 'object' );
@ -674,6 +693,12 @@ class TemplateDataBlob {
$data->description :
wfMessage( 'templatedata-doc-desc-empty' )->inLanguage( $lang )->text()
)
. Html::element(
'p',
array(),
// Messages: templatedata-modal-format-inline, templatedata-modal-format-block
wfMessage( 'templatedata-doc-format-' . $data->format )->inLanguage( $lang )->text()
)
. '<table class="wikitable mw-templatedata-doc-params sortable">'
. Html::element(
'caption',

View file

@ -111,6 +111,8 @@
"templatedata-modal-errormsg",
"templatedata-modal-errormsg-import-noparams",
"templatedata-modal-errormsg-import-paramsalreadyexist",
"templatedata-modal-format-inline",
"templatedata-modal-format-block",
"templatedata-modal-json-error-replace",
"templatedata-modal-notice-import-numparams",
"templatedata-modal-placeholder-paramkey",
@ -151,6 +153,7 @@
"templatedata-modal-title-language",
"templatedata-modal-title-paramorder",
"templatedata-modal-title-templatedesc",
"templatedata-modal-title-templateformat",
"templatedata-modal-title-templateparam-details",
"templatedata-modal-title-templateparams",
"templatedata-helplink",

View file

@ -13,6 +13,8 @@
"apihelp-templatedata-param-lang": "Return localized values in this language. By default all available translations are returned.",
"templatedata-desc": "Implement data storage for template parameters (using JSON)",
"templatedata-doc-desc-empty": "No description.",
"templatedata-doc-format-inline": "This template prefers inline formatting of parameters.",
"templatedata-doc-format-block": "This template prefers block formatting of parameters.",
"templatedata-doc-no-params-set": "No parameters specified",
"templatedata-doc-param-autovalue": "Auto value",
"templatedata-doc-param-autovalue-empty": "empty",
@ -37,6 +39,7 @@
"templatedata-helplink-target": "//www.mediawiki.org/wiki/Special:MyLanguage/Help:TemplateData",
"templatedata-invalid-duplicate-value": "Property \"$1\" (\"$3\") is a duplicate of \"$2\".",
"templatedata-invalid-empty-array": "Property \"$1\" must have at least one value in its array.",
"templatedata-invalid-format": "Property \"$1\" is expected to be \"inline\" or \"block\".",
"templatedata-invalid-length": "Data too large to save ({{formatnum:$1}} {{PLURAL:$1|byte|bytes}}, {{PLURAL:$2|limit is}} {{formatnum:$2}})",
"templatedata-invalid-missing": "Required property \"$1\" not found.",
"templatedata-invalid-param": "Invalid parameter \"$1\" for property \"$2\".",
@ -59,6 +62,8 @@
"templatedata-modal-errormsg": "Errors found. Please make sure there are no empty or duplicate parameter names, and that the parameter name does not include \"$1\", \"$2\" or \"$3\".",
"templatedata-modal-errormsg-import-noparams": "No new parameters found during import.",
"templatedata-modal-errormsg-import-paramsalreadyexist": "{{PLURAL:$1|One parameter was not imported, because it already exists|Some parameters were not imported, because they already exist}} in the editor: $1",
"templatedata-modal-format-inline": "Inline",
"templatedata-modal-format-block": "Block",
"templatedata-modal-json-error-replace": "Replace",
"templatedata-modal-notice-import-numparams": "$1 new {{PLURAL:$1|parameter was|parameters were}} imported: $2",
"templatedata-modal-placeholder-paramkey": "Parameter name",
@ -98,6 +103,7 @@
"templatedata-modal-title-language": "Language",
"templatedata-modal-title-paramorder": "Parameter order",
"templatedata-modal-title-templatedesc": "Template description ($1)",
"templatedata-modal-title-templateformat": "Template preferred format",
"templatedata-modal-title-templateparam-details": "Parameter details: $1",
"templatedata-modal-title-templateparams": "Template parameters"
}

View file

@ -22,6 +22,8 @@
"apihelp-templatedata-param-lang": "{{doc-apihelp-param|templatedata|lang}}",
"templatedata-desc": "{{desc|name=Template Data|url=https://www.mediawiki.org/wiki/Extension:TemplateData}}",
"templatedata-doc-desc-empty": "Displayed when a template has no description (should be a valid sentence).\n{{Identical|No description}}",
"templatedata-doc-format-inline": "Use inline formatting of the template parameters in wikitext.",
"templatedata-doc-format-block": "Use block formatting of the template parameters in wikitext.",
"templatedata-doc-no-params-set": "A message shown when there are no parameters set in the TemplateData string.",
"templatedata-doc-param-autovalue": "Used as column heading in the table for auto fill value.\n{{Related|Templatedata-doc-param}}",
"templatedata-doc-param-autovalue-empty": "Displayed when a template parameter has no auto filled value (should not be a full sentence, used in a table).\n{{Identical|Empty}}",
@ -46,6 +48,7 @@
"templatedata-helplink-target": "{{ignore}} The target of the link to the TemplateData documentation",
"templatedata-invalid-duplicate-value": "Displayed when an array that must only contain unique values contains a duplicate.\n* $1 - name of property containing the duplicate\n* $2 - name of property with first occurrence of value\n* $3 - the value being duplicated",
"templatedata-invalid-empty-array": "Error message when a property that must be non-empty is empty. Parameters:\n* $1 - property name (\"paramOrder\" or \"sets.{$setNr}.params\")",
"templatedata-invalid-format": "Error message when format property gets an unexpected value.",
"templatedata-invalid-length": "Error message when generated JSON's length exceed database limits.\n* $1 - length of generated JSON\n* $2 - maximal allowed length",
"templatedata-invalid-missing": "Error message when a required property is not found.\n* $1 - name of property. e.g. \"params\"\n* $2 - type of property (Unused)",
"templatedata-invalid-param": "Error message for when the supplied parameter is invalid.\n* $1 - name of parameter. e.g. \"username\"\n* $2 - name of property. e.g. maps property \"applicationUser\"",
@ -68,6 +71,8 @@
"templatedata-modal-errormsg": "Error message that appears in the TemplateData generator GUI in case there are empty, duplicate or invalid parameter names.\n\nInvalid characters are supplied as parameters to avoid parsing errors in translation strings.\n\nParameters:\n* $1 - pipe (<code>|</code>)\n* $2 - equal sign (<code>=</code>)\n* $3 - double curly brackets (<code><nowiki>}}</nowiki></code>)",
"templatedata-modal-errormsg-import-noparams": "Error message that appears in the TemplateData generator GUI in case no template parameters were found during the import attempt.",
"templatedata-modal-errormsg-import-paramsalreadyexist": "Error message that appears when some parameters were not imported from the template code because they already exist in the editor.\n\nParameters:\n* $1 - list of parameters that were not imported",
"templatedata-modal-format-inline": "Label for inline format",
"templatedata-modal-format-block": "Label for block format",
"templatedata-modal-json-error-replace": "Label for the button in the error message, agreeing to replace the existing faulty TemplateData string with a new one.\n{{Identical|Replace}}",
"templatedata-modal-notice-import-numparams": "Message that appears in the TemplateData generator GUI showing how many new parameters were imported into the GUI from an existing template.\n\nParameters:\n* $1 - number of parameters\n* $2 - list of parameters that were imported",
"templatedata-modal-placeholder-paramkey": "Placeholder for the input that contains new parameter name in the add parameter panel in the edit dialog.",
@ -107,6 +112,7 @@
"templatedata-modal-title-language": "Label for the language dropdown in the edit menu.\n{{Identical|Language}}",
"templatedata-modal-title-paramorder": "The title for the parameter order drag/drop widget in the edit dialog.",
"templatedata-modal-title-templatedesc": "The title for the template description textbox. Parameters:\n* $1 - currently used language",
"templatedata-modal-title-templateformat": "The title for the template preferred format",
"templatedata-modal-title-templateparam-details": "The title for the parameter information section. Parameters:\n* $1 - The parameter name",
"templatedata-modal-title-templateparams": "The title for the template parameters table\nof a single template."
}

View file

@ -17,9 +17,9 @@ mw.TemplateData.Model = function mwTemplateDataModel( config ) {
this.params = {};
this.description = {};
this.paramOrder = [];
this.format = 'inline';
this.paramOrderChanged = false;
this.paramIdentifierCounter = 0;
this.originalTemplateDataObject = null;
this.sourceCodeParameters = [];
};
@ -274,6 +274,10 @@ mw.TemplateData.Model.static.newFromObject = function ( tdObject, paramsInSource
model.setTemplateParamOrder( tdObject.paramOrder );
}
if ( tdObject.format ) {
model.setTemplateFormat( tdObject.format );
}
return model;
};
@ -554,6 +558,20 @@ mw.TemplateData.Model.prototype.setTemplateParamOrder = function ( orderArray )
this.emit( 'change-paramOrder', orderArray );
};
/**
* Set template format.
*
* @param {string} [format='inline'] Preferred format
* @fires change-format
*/
mw.TemplateData.Model.prototype.setTemplateFormat = function ( format ) {
format = format || 'inline';
if ( this.format !== format ) {
this.format = format;
this.emit( 'change-format', format );
}
};
/**
* Add a key to the end of the paramOrder
*
@ -604,6 +622,15 @@ mw.TemplateData.Model.prototype.getTemplateParamOrder = function () {
return this.paramOrder;
};
/**
* Retrieve the template preferred format
*
* @return {string} Preferred format
*/
mw.TemplateData.Model.prototype.getTemplateFormat = function () {
return this.format;
};
/**
* Set a specific parameter's property
*
@ -834,6 +861,9 @@ mw.TemplateData.Model.prototype.outputTemplateDataString = function () {
delete result.paramOrder;
}
// Format
result.format = this.format;
// Attach sets as-is for now
// TODO: Work properly with sets
if ( original.sets ) {

View file

@ -78,7 +78,7 @@ mw.TemplateData.Dialog.static.actions = [
*/
mw.TemplateData.Dialog.prototype.initialize = function () {
var templateParamsFieldset, addParamFieldlayout, languageActionFieldLayout,
paramOrderFieldset;
paramOrderFieldset, templateFormatFieldSet;
// Parent method
mw.TemplateData.Dialog.super.prototype.initialize.call( this );
@ -120,6 +120,7 @@ mw.TemplateData.Dialog.prototype.initialize = function () {
this.languagePanelButton = new OO.ui.ButtonWidget( {
label: mw.msg( 'templatedata-modal-button-add-language' )
} );
languageActionFieldLayout = new OO.ui.ActionFieldLayout(
this.languageDropdownWidget,
this.languagePanelButton,
@ -154,6 +155,24 @@ mw.TemplateData.Dialog.prototype.initialize = function () {
} );
templateParamsFieldset.$element.append( this.paramSelectWidget.$element );
this.templateFormatSelectWidget = new OO.ui.ButtonSelectWidget();
this.templateFormatSelectWidget.addItems( [
// TODO: add nice icons?
new OO.ui.ButtonOptionWidget( {
data: 'inline',
label: mw.msg( 'templatedata-modal-format-inline' )
} ),
new OO.ui.ButtonOptionWidget( {
data: 'block',
label: mw.msg( 'templatedata-modal-format-block' )
} )
] );
templateFormatFieldSet = new OO.ui.FieldsetLayout( {
label: mw.msg( 'templatedata-modal-title-templateformat' )
} );
templateFormatFieldSet.$element.append( this.templateFormatSelectWidget.$element );
// Param details panel
this.$paramDetailsContainer = $( '<div>' )
.addClass( 'tdg-TemplateDataDialog-paramDetails' );
@ -164,6 +183,7 @@ mw.TemplateData.Dialog.prototype.initialize = function () {
this.paramListNoticeLabel.$element,
languageActionFieldLayout.$element,
this.templateDescriptionFieldset.$element,
templateFormatFieldSet.$element,
paramOrderFieldset.$element,
templateParamsFieldset.$element
);
@ -213,6 +233,8 @@ mw.TemplateData.Dialog.prototype.initialize = function () {
this.languagePanelButton.connect( this, { click: 'onLanguagePanelButton' } );
this.languageDropdownWidget.getMenu().connect( this, { select: 'onLanguageDropdownWidgetSelect' } );
this.paramSelectWidget.connect( this, { choose: 'onParamSelectWidgetChoose' } );
this.templateFormatSelectWidget.connect( this, { choose: 'onTemplateFormatSelectWidgetChoose' } );
};
/**
@ -414,6 +436,14 @@ mw.TemplateData.Dialog.prototype.onParamSelectWidgetChoose = function ( item ) {
this.switchPanels( 'editParam' );
}
};
/**
* Respond to choose event from the template format select widget
*
* @param {OO.ui.OptionWidget} item Format item
*/
mw.TemplateData.Dialog.prototype.onTemplateFormatSelectWidgetChoose = function ( item ) {
this.model.setTemplateFormat( item.getData() );
};
mw.TemplateData.Dialog.prototype.onParamPropertyInputChange = function ( property, value ) {
var err = false,
@ -855,6 +885,10 @@ mw.TemplateData.Dialog.prototype.getSetupProcess = function ( data ) {
mw.TemplateData.Dialog.prototype.setupDetailsFromModel = function () {
// Set up description
this.descriptionInput.setValue( this.model.getTemplateDescription( this.language ) );
// Set up format
this.templateFormatSelectWidget.selectItemByData( this.model.getTemplateFormat() );
// Repopulate the parameter list
this.repopulateParamSelectWidget();
};

View file

@ -51,6 +51,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
"params": {},
"paramOrder": [],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -104,6 +105,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
},
"paramOrder": ["foo"],
"sets": [],
"format": "inline",
"maps": {}
}
',
@ -136,6 +138,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
},
"paramOrder": ["comment"],
"sets": [],
"format": "inline",
"maps": {}
}
',
@ -185,6 +188,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
},
"paramOrder": ["nickname"],
"sets": [],
"format": "inline",
"maps": {}
}
',
@ -246,6 +250,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
},
"paramOrder": ["1d", "2d"],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -370,6 +375,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
"params": ["bar", "quux"]
}
],
"format": "inline",
"maps": {}
}',
'status' => true
@ -421,6 +427,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
},
"paramOrder": ["bar"],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -485,13 +492,22 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
}',
'status' => 'Property "maps.application.things[0][0]" is expected to be of type "string".'
),
array(
'input' => '{
"params": {
"foo": {}
},
"format": "meshuggah format"
}',
'status' => 'Property "format" is expected to be "inline" or "block".'
),
array(
// Should be long enough to trigger this condition after gzipping.
'input' => '{
"description": "' . self::generatePseudorandomString( 100000, 42 ) . '",
"params": {}
}',
'status' => 'Data too large to save (75,215 bytes, limit is 65,535)'
'status' => 'Data too large to save (75,230 bytes, limit is 65,535)'
),
);
$calls = array();
@ -564,6 +580,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
"params": {},
"sets": [],
"maps": {},
"format": "inline",
"paramOrder": []
}';
} else {
@ -656,6 +673,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
"params": {},
"paramOrder": [],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -673,6 +691,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
"paramOrder": [],
"params": {},
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -694,6 +713,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
"params": {},
"paramOrder": [],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -714,6 +734,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
"params": {},
"paramOrder": [],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -735,6 +756,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
"params": {},
"paramOrder": [],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -771,6 +793,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
},
"paramOrder": ["foo"],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -807,6 +830,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
},
"paramOrder": ["foo"],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -843,6 +867,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
},
"paramOrder": ["foo"],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -888,6 +913,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
"params": ["foo"]
}
],
"format": "inline",
"maps": {}
}
',
@ -987,6 +1013,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
},
"paramOrder": ["foo", "bar", "baz"],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -1044,6 +1071,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
},
"paramOrder": ["baz", "foo", "bar"],
"sets": [],
"format": "inline",
"maps" : {}
}
',
@ -1072,6 +1100,7 @@ class TemplateDataBlobTest extends MediaWikiTestCase {
"params": {},
"paramOrder": [],
"sets": [],
"format": "inline",
"maps" : {}
}
',

View file

@ -134,7 +134,8 @@
' "day"\n' +
' ]\n' +
' }\n' +
' ]\n' +
' ],\n' +
' "format": "inline"\n' +
'}';
finalJsonStringOnlyParamOrder = '{\n' +
' "description": {\n' +
@ -161,7 +162,8 @@
' "newParam2",\n' +
' "newParam3",\n' +
' "newParam4"\n' +
' ]\n' +
' ],\n' +
' "format": "inline"\n' +
'}';
// Test validation tools
@ -632,4 +634,30 @@
} );
} );
// Test model gets default format
QUnit.asyncTest( 'TemplateData sourceHandler adding default format', function ( assert ) {
var sourceHandler = new mw.TemplateData.SourceHandler(),
simpleTemplateDataNoFormat = '<templatedata>{\n' +
' "params": {}\n' +
'}</templatedata>',
simpleTemplateDataDefaultFormat = '{\n' +
' "params": {},\n' +
' "format": "inline"\n' + // default format
'}';
QUnit.expect( 1 );
sourceHandler.buildModel( simpleTemplateDataNoFormat )
.done( function ( model ) {
assert.equal(
model.outputTemplateDataString(),
simpleTemplateDataDefaultFormat,
'Final templatedata output'
);
} )
.always( function () {
QUnit.start();
} );
} );
}() );