/*
* AutotranslateHelper
*
* Creates an {{autotranslate}} template very quickly, by automating the creation
* of all required subpages.
* To launch the process, go on [[User:Antoine WMFr/AutotranslateHelper]]
*
* Author : [[User:0x010C]]
* Creation : 31 March 2017
* Last edit : 3 April 2017
*/
//<nowiki>
mw.loader.using( [ 'mediawiki.util', 'oojs-ui' ], function () {
const baseTemplate = '{{autotranslate|base=$(title)}}<includeonly>$(categories)</includeonly><noinclude>\n{{documentation}}\n</noinclude>';
const categoryTemplate = '\n[[Category:$(category)|{{PAGENAME}}]]';
const layoutTemplate = '$(layout)<noinclude>\n[[Category:Layout templates|{{PAGENAME}}]]\n</noinclude>';
const langSubpageTemplate = '{{$(title)/layout|lang={{subst:SUBPAGENAME}}\n$(params)\n}}<noinclude>\n{{translated tag|source}}\n</noinclude>';
const langTemplate = '{{subst:lle}}';
const docTemplate = '{{TemplateBox\n|name=$(title)\n|desc=$(description)\n|namespace=$(namespace)\n|usergroup=$(usergroup)\n|placement=$(placement)\n|usage-notes=\n|type=\n|example=\n|i18n-method=autotranslate\n|i18n-desc=\n|seealso=$(seealso)\n|setscats=$(setscats)\n|lines=\n|shorthand=\n|relieson=\n}}';
const setcatsTemplate = '\n*{{cl|$(category)}}';
const messages = {
'en': {
'athelper-save': 'Generate!',
'athelper-notif-progress': 'Template $1 out of $2 created.',
'athelper-notif-title': 'Generation in progress...',
'athelper-pageexists': 'There is already a template with this title on Commons...',
'athelper-error-message': 'Oops... Something wrong happend.',
'athelper-error-title': 'Error',
'athelper-error-log': 'Unable to create the page named $1',
'athelper-success-message': 'The process is over. You will be redirected to the main template page.',
'athelper-success-title': 'End of the process!',
'athelper-base-title': 'General settings',
'athelper-name-label': 'Template title',
'athelper-name-help': '',
'athelper-layout-label': 'Layout',
'athelper-layout-help': '',
'athelper-parameters-label': 'Layout parameters',
'athelper-parameters-help': '',
'athelper-categories-label': 'Categories',
'athelper-categories-help': '',
'athelper-langs-label': 'Languages',
'athelper-langs-help': '',
'athelper-lang-title': 'Layout`s parameters in language: $1',
'athelper-doc-title': 'Documentation',
'athelper-description-label': 'Description',
'athelper-description-help': '',
'athelper-namespace-label': 'Namespace',
'athelper-namespace-help': '',
'athelper-doc-categories-label': 'Categories',
'athelper-doc-categories-help': '',
'athelper-usergroup-label': 'Authorised user group',
'athelper-usergroup-help': '',
'athelper-placement-label': 'Placement',
'athelper-placement-help': '',
'athelper-seealso-label': 'See also',
'athelper-seealso-help': '',
},
'fr': {
'athelper-save': 'Générer !',
'athelper-notif-progress': 'Modèle $1 sur $2 créé.',
'athelper-notif-title': 'Génération en cours...',
'athelper-pageexists': 'Une page existe déjà avec ce titre sur Commons...',
'athelper-error-message': 'Oups... Une erreur innatendu est survenu.',
'athelper-error-title': 'Erreur',
'athelper-error-log': 'Impossible de créer la page $1',
'athelper-success-message': 'Vous allez être redirigé sur la page du modèle principal.',
'athelper-success-title': 'Génération terminé !',
'athelper-base-title': 'Configuration général',
'athelper-name-label': 'Nom',
'athelper-name-help': 'Titre à donner au modèle principal, SANS le prefix Template:',
'athelper-layout-label': 'Layout de base',
'athelper-layout-help': 'Code Wikitext/HTML servant de structure au bandeau. Si vous ne savez pas quoi mettre, songez à utilisez un modèle pré-rempli.',
'athelper-parameters-label': 'Paramètres dans le layout',
'athelper-parameters-help': 'Paramètres présents dans le layout, servant à la traduction.',
'athelper-categories-label': 'Catégories',
'athelper-categories-help': 'Catégories qui contiendront les pages sur les-quels le modèle sera transclu.',
'athelper-langs-label': 'Langues à générer',
'athelper-langs-help': 'Code ISO 639 des langues à traduire dès maintenant.',
'athelper-lang-title': 'Paramètres du modèle dans la langue : $1',
'athelper-doc-title': 'Documentation',
'athelper-description-label': 'Description',
'athelper-description-help': 'Décrivez le modèle, son but,...',
'athelper-namespace-label': 'Espace de nom',
'athelper-namespace-help': 'L\'espace de nom où s\'applique le modèle.',
'athelper-doc-categories-label': 'Catégories',
'athelper-doc-categories-help': 'Catégories dans lesquels catégoriser le modèle lui-même (et non les pages transcluant le modèle).',
'athelper-usergroup-label': 'Groupe d\'utilisateurs autorisé',
'athelper-usergroup-help': 'Le groupe d\'utilisateurs qui est autorisé à déposer le modèle.',
'athelper-placement-label': 'Positionnement du modèle',
'athelper-placement-help': 'Position dans la page où le modèle doit être apposé.',
'athelper-seealso-label': 'Voir aussi',
'athelper-seealso-help': 'Lien vers des pages et/ou modèles ayant un lien avec celui-ci.',
}
};
mw.messages.set( messages[ 'en' ] );
var lang = mw.config.get( 'wgUserLanguage' );
if ( lang && lang != 'en' && lang in messages ) {
mw.messages.set( messages[ lang ] );
}
var AutotranslateHelper = function () {
this.booklet = undefined;
this.basePage = undefined;
this.docPage = undefined;
this.langPages = {};
this.langCodes = [];
this.params = [];
this.generateInterface();
this.fetchPreload();
};
AutotranslateHelper.prototype.generateInterface = function () {
var self = this;
var saveButton = new OO.ui.ButtonWidget( {
label: mw.msg( 'athelper-save' ),
icon: 'next',
iconTitle: 'Save',
flags: [ 'primary', 'progressive' ]
} );
saveButton.on( 'click', function() {
mw.loader.using( [ 'mediawiki.api.edit' ], function() {
self.generateTemplates();
} );
} );
this.booklet = new OO.ui.BookletLayout( {
outlined: true
} );
$( '#bodyContent' ).empty();
var buttonsContainer = $( '<div>' ).css( 'text-align', 'right' ).append( saveButton.$element[ 0 ] );
var mainContainer = $( '<div>' ).css('height', '500px').css( 'border', '1px solid #a2a9b1' ).css( 'border-radius', '2px' ).css( 'position', 'relative' ).append( this.booklet.$element );
$( '#bodyContent' ).append( buttonsContainer ).append( mainContainer );
this.basePage = new BasePageLayout( this, 'base' );
this.docPage = new DocPageLayout( this, 'doc' );
this.booklet.addPages ( [ this.basePage, this.docPage ] );
};
AutotranslateHelper.prototype.fetchPreload = function () {
if ( mw.util.getParamValue( 'preload' ) !== null ) {
var self = this;
var preloadPage = mw.util.getParamValue( 'preload' );
if ( preloadPage[ 0 ] === "/" ) {
preloadPage = mw.config.get( 'wgPageName' ) + preloadPage;
}
var api = new mw.Api();
api.get( {
action: 'query',
prop: 'revisions',
rvprop: [ 'content' ],
titles: String( preloadPage ),
formatversion: '2',
} ).then( function( data ) {
preload = JSON.parse( data.query.pages[ 0 ].revisions[ 0 ].content );
self.basePage.nameInput.setValue( preload.title );
self.basePage.layoutInput.setValue( preload.layout );
self.basePage.paramsInput.setItemsFromData( preload.parameters );
self.basePage.categoriesInput.setItemsFromData( preload.categories );
self.docPage.descriptionInput.setValue( preload.doc.description );
self.docPage.namespaceInput.setValue( preload.doc.namespace );
self.docPage.usergroupInput.setValue( preload.doc.usergroup );
self.docPage.placementInput.setValue( preload.doc.placement );
self.docPage.categoriesInput.setItemsFromData( preload.doc.categories );
self.docPage.seealsoInput.setValue( preload.doc.seealso );
} );
}
};
AutotranslateHelper.prototype.updateLangPages= function ( langCodes ) {
var self = this;
var newCodes = langCodes.filter( function( i ) { return self.langCodes.indexOf( i ) < 0; } );
$.each( newCodes, function( key, code ) {
self.addLangPage( code );
} );
var oldCodes = self.langCodes.filter( function( i ) { return langCodes.indexOf( i ) < 0; } );
$.each( oldCodes, function( key, code ) {
self.removeLangPage( code );
} );
this.langCodes = langCodes;
};
AutotranslateHelper.prototype.addLangPage= function ( langCode ) {
if( this.langPages[ langCode ] === undefined ) {
langPage = new LangPageLayout( langCode, this.params, { label: langCode } );
this.langPages[ langCode ] = langPage;
}
this.booklet.addPages ( [ this.langPages[ langCode ] ] );
};
AutotranslateHelper.prototype.removeLangPage= function ( langCode ) {
this.booklet.removePages ( [ this.langPages[ langCode ] ] );
};
AutotranslateHelper.prototype.updateParams= function ( params ) {
var self = this;
var newParams = params.filter( function( i ) { return self.params.indexOf( i ) < 0; } );
$.each( newParams, function( key, param ) {
$.each( self.langPages, function( key, langPage ) {
langPage.addParam( param );
} );
} );
var oldParams = self.params.filter( function( i ) { return params.indexOf( i ) < 0; } );
$.each( oldParams, function( key, param ) {
$.each( self.langPages, function( key, langPage ) {
langPage.removeParam( param );
} );
} );
this.params = params;
};
AutotranslateHelper.prototype.generateTemplates = function () {
var api = new mw.Api();
var self = this;
this.nbTemplates = this.langCodes.length + 4;
this.createdTemplates = 0;
var baseTitle = this.basePage.nameInput.getValue();
var layout = this.basePage.layoutInput.getValue();
var categories = this.basePage.categoriesInput.getItemsData();
var description = this.docPage.descriptionInput.getValue();
var namespace = this.docPage.namespaceInput.getValue();
var usergroup = this.docPage.usergroupInput.getValue();
var placement = this.docPage.placementInput.getValue();
var docCategories = this.docPage.categoriesInput.getItemsData();
var seealso = this.docPage.seealsoInput.getValue();
var categoriesContent = '';
var setscats = '';
var docCategoriesContent = '';
$.each( categories, function( key, category ) {
categoriesContent += categoryTemplate.replace( '$(category)', category );
setscats += setcatsTemplate.replace( '$(category)', category );
} );
$.each( docCategories, function( key, category ) {
docCategoriesContent += categoryTemplate.replace( '$(category)', category );
} );
api.create( 'Template:' + baseTitle, {
summary: 'Template created using [[User:Antoine_WMFr/AutotranslateHelper|AutotranslateHelper]]',
}, baseTemplate.replace( '$(title)', baseTitle ).replace( '$(categories)', categoriesContent ) )
.fail( function( data ) {
self.error( 'Template:' + baseTitle, data );
} )
.then( function() {
self.log();
api.create( 'Template:' + baseTitle + '/layout', {
summary: 'Template created using [[User:Antoine_WMFr/AutotranslateHelper|AutotranslateHelper]]',
}, layoutTemplate.replace( '$(layout)', layout ) )
.fail( function( data ) {
self.error( 'Template:' + baseTitle + '/layout', data );
} )
.then( function() {
self.log();
} );
api.create( 'Template:' + baseTitle + '/doc', {
summary: 'Template created using [[User:Antoine_WMFr/AutotranslateHelper|AutotranslateHelper]]',
}, docTemplate.replace( '$(title)', baseTitle ).replace( '$(description)', description ).replace( '$(namespace)', namespace ).replace( '$(usergroup)', usergroup ).replace( '$(placement)', placement ).replace( '$(setscats)', setscats ).replace( '$(seealso)', seealso ) )
.fail( function( data ) {
self.error( 'Template:' + baseTitle + '/doc', data );
} )
.then( function() {
self.log();
} );
$.each( self.langCodes, function( key, langCode ) {
var paramsContent = '';
$.each( self.params, function(key, param) {
paramsContent += '\n|' + param + '=' + self.langPages[langCode].paramInputs[param].getValue();
} );
api.create( 'Template:' + baseTitle + '/' + langCode, {
summary: 'Template created using [[User:Antoine_WMFr/AutotranslateHelper|AutotranslateHelper]]',
}, langSubpageTemplate.replace( '$(title)', baseTitle ).replace( '$(params)', paramsContent ) )
.fail( function( data ) {
self.error('Template:' + baseTitle + '/' + langCode, data );
} )
.then( function() {
self.log();
} );
} );
} );
};
AutotranslateHelper.prototype.log = function() {
this.createdTemplates++;
mw.notify( mw.msg( 'athelper-notif-progress', this.createdTemplates, this.nbTemplates ), { title: mw.msg( 'athelper-notif-title' ) } );
if ( this.createdTemplates +1 === this.nbTemplates ) {
this.GenerateLastTemplate();
}
};
AutotranslateHelper.prototype.error = function( title, data ) {
if ( data === 'articleexists' ) {
OO.ui.alert( mw.msg( 'athelper-pageexists' ), {
title: mw.msg( 'athelper-error-title' )
} );
}
else {
OO.ui.alert( mw.msg( 'athelper-error-message' ), {
title: mw.msg( 'athelper-error-title' )
} );
}
console.log( mw.msg( 'athelper-error-log', title ) );
console.log( data );
};
AutotranslateHelper.prototype.GenerateLastTemplate = function() {
var api = new mw.Api();
var self = this;
var baseTitle = this.basePage.nameInput.getValue();
api.create( 'Template:' + baseTitle + '/lang', {
summary: 'Template created using [[User:Antoine_WMFr/AutotranslateHelper|AutotranslateHelper]]',
}, langTemplate )
.fail( function(data) {
self.error( 'Template:' + baseTitle + '/lang', data );
} )
.then( function() {
mw.notify( mw.msg( 'athelper-success-message' ), { title: mw.msg( 'athelper-success-title' ) } );
setTimeout( function() {
window.location.href = mw.util.getUrl( 'Template:' + baseTitle );
}, 700 );
} );
};
var BasePageLayout = function( autotranslateHelper, name, config ) {
BasePageLayout.super.call( this, name, config );
this.nameInput = new OO.ui.TextInputWidget( {} );
this.layoutInput = new OO.ui.TextInputWidget( {
multiline: true,
value: '',
autosize: true,
rows: 5,
maxRows: 12,
} );
this.paramsInput = new OO.ui.CapsuleMultiselectWidget( {
label: 'CapsuleMultiselectWidget',
menu: {
items: []
},
allowArbitrary: true,
allowDuplicates: false,
} );
this.paramsInput.on( 'change', function( data ) {
if ( data.length === 0 ) {
autotranslateHelper.updateParams( [] );
}
else if ( typeof( data[ 0 ] ) === 'string' ) {
autotranslateHelper.updateParams( data );
}
} );
this.categoriesInput = new OO.ui.CapsuleMultiselectWidget( {
label: 'CapsuleMultiselectWidget',
menu: {
items: []
},
allowArbitrary: true,
allowDuplicates: false,
} );
//TODO: Category search
this.langsInput = new OO.ui.CapsuleMultiselectWidget( {
label: 'CapsuleMultiselectWidget',
menu: {
items: [
new OO.ui.MenuOptionWidget( {
data: 'fr',
label: 'fr'
} ),
new OO.ui.MenuOptionWidget( {
data: 'en',
label: 'en'
} ),
]
},
allowArbitrary: true,
allowDuplicates: false,
} );
this.langsInput.on( 'change', function( data ) {
if ( data.length === 0 ) {
autotranslateHelper.updateLangPages( [] );
}
else if ( typeof( data[ 0 ] ) === 'string' ) {
autotranslateHelper.updateLangPages( data );
}
} );
// Create a Fieldset layout.
var fieldset = new OO.ui.FieldsetLayout( {
label: mw.msg( 'athelper-base-title' ),
} );
fieldset.addItems( [
new OO.ui.FieldLayout( this.nameInput, {
label: mw.msg( 'athelper-name-label' ),
align: 'left',
help: mw.msg( 'athelper-name-help' ),
} ),
new OO.ui.FieldLayout( this.layoutInput, {
label: mw.msg( 'athelper-layout-label' ),
align: 'left',
help: mw.msg( 'athelper-layout-help' ),
} ),
new OO.ui.FieldLayout( this.paramsInput, {
label: mw.msg( 'athelper-parameters-label' ),
align: 'left',
help: mw.msg( 'athelper-parameters-help' ),
} ),
new OO.ui.FieldLayout( this.categoriesInput, {
label: mw.msg( 'athelper-categories-label' ),
align: 'left',
help: mw.msg( 'athelper-categories-help' ),
} ),
new OO.ui.FieldLayout( this.langsInput, {
label: mw.msg( 'athelper-langs-label' ),
align: 'left',
help: mw.msg( 'athelper-langs-help' ),
} )
] );
this.$element.append( fieldset.$element );
};
OO.inheritClass( BasePageLayout, OO.ui.PageLayout );
BasePageLayout.prototype.setupOutlineItem = function () {
this.outlineItem.setLabel( mw.msg( 'athelper-base-title' ) );
};
var DocPageLayout = function( autotranslateHelper, name, config ) {
DocPageLayout.super.call( this, name, config );
this.descriptionInput = new OO.ui.TextInputWidget( {
multiline: true,
autosize: true,
rows: 4,
} );
this.namespaceInput = new OO.ui.DropdownInputWidget( {
options:[
{ data: 'all', label: 'all' },
{ data: 'talks', label: 'talks' },
{ data: 'contents', label: 'contents' },
{ data: 'Main', label: 'Main' },
{ data: 'Talk', label: 'Talk' },
{ data: 'User', label: 'User' },
{ data: 'User talk', label: 'User talk' },
{ data: 'Commons', label: 'Commons' },
{ data: 'Commons talk', label: 'Commons talk' },
{ data: 'File', label: 'File' },
{ data: 'File talk', label: 'File talk' },
{ data: 'MediaWiki', label: 'MediaWiki' },
{ data: 'MediaWiki talk', label: 'MediaWiki talk' },
{ data: 'Template', label: 'Template' },
{ data: 'Template talk', label: 'Template talk' },
{ data: 'Help', label: 'Help' },
{ data: 'Help talk', label: 'Help talk' },
{ data: 'Category', label: 'Category' },
{ data: 'Category talk', label: 'Category talk' },
{ data: 'Creator', label: 'Creator' },
{ data: 'Creator talk', label: 'Creator talk' },
{ data: 'Special', label: 'Special' },
],
} );
this.usergroupInput = new OO.ui.DropdownInputWidget( {
options:[
{ data: 'all', label: 'all' },
{ data: 'bot', label: 'bot' },
{ data: 'sysop', label: 'sysop' },
{ data: 'bureaucrat', label: 'bureaucrat' },
{ data: 'checkuser', label: 'checkuser' },
{ data: 'licensereviewer', label: 'licensereviewer' },
{ data: 'otrs', label: 'otrs' },
{ data: 'autoconfirmed', label: 'autoconfirmed' },
{ data: 'autopatrolled', label: 'autopatrolled' },
{ data: 'filemover', label: 'filemover' },
{ data: 'oversight', label: 'oversight' },
{ data: 'patroller', label: 'patroller' },
{ data: 'rollbacker', label: 'rollbacker' },
{ data: 'steward', label: 'steward' },
],
} );
this.placementInput = new OO.ui.DropdownInputWidget( {
options:[
{ data: 'top', label: 'top' },
{ data: 'bottom', label: 'bottom' },
{ data: 'licence', label: 'licence' },
{ data: 'source', label: 'source' },
],
} );
this.categoriesInput = new OO.ui.CapsuleMultiselectWidget( {
label: 'CapsuleMultiselectWidget',
menu: {
items: []
},
allowArbitrary: true,
allowDuplicates: false,
} );
//TODO: Category search
this.seealsoInput = new OO.ui.TextInputWidget( {
multiline: true,
autosize: true,
rows: 2,
} );
// Create a Fieldset layout.
var fieldset = new OO.ui.FieldsetLayout( {
label: mw.msg( 'athelper-base-title' ),
} );
fieldset.addItems( [
new OO.ui.FieldLayout( this.descriptionInput, {
label: mw.msg( 'athelper-description-label' ),
align: 'left',
help: mw.msg( 'athelper-description-help' ),
} ),
new OO.ui.FieldLayout( this.namespaceInput, {
label: mw.msg( 'athelper-namespace-label' ),
align: 'left',
help: mw.msg( 'athelper-namespace-help' ),
} ),
new OO.ui.FieldLayout( this.usergroupInput, {
label: mw.msg( 'athelper-usergroup-label' ),
align: 'left',
help: mw.msg( 'athelper-usergroup-help' ),
} ),
new OO.ui.FieldLayout( this.placementInput, {
label: mw.msg( 'athelper-placement-label' ),
align: 'left',
help: mw.msg( 'athelper-placement-help' ),
} ),
new OO.ui.FieldLayout( this.categoriesInput, {
label: mw.msg( 'athelper-doc-categories-label' ),
align: 'left',
help: mw.msg( 'athelper-doc-categories-help' ),
} ),
new OO.ui.FieldLayout( this.seealsoInput, {
label: mw.msg( 'athelper-seealso-label' ),
align: 'left',
help: mw.msg( 'athelper-seealso-help' ),
} ),
] );
this.$element.append( fieldset.$element );
};
OO.inheritClass( DocPageLayout, OO.ui.PageLayout );
DocPageLayout.prototype.setupOutlineItem = function () {
this.outlineItem.setLabel( mw.msg( 'athelper-doc-title' ) );
};
var LangPageLayout = function( name, params, config ) {
LangPageLayout.super.call( this, name, config );
this.label = config.label;
this.paramInputs = {};
this.params = [];
this.fieldset = new OO.ui.FieldsetLayout( {
label: mw.msg( 'athelper-lang-title', config.label ),
} );
this.$element.append( this.fieldset.$element );
var self = this;
$.each( params, function( key, value ) {
self.addParam( value );
} );
};
OO.inheritClass( LangPageLayout, OO.ui.PageLayout );
LangPageLayout.prototype.setupOutlineItem = function () {
this.outlineItem.setLabel( this.label );
this.outlineItem.setLevel( 1 );
};
LangPageLayout.prototype.addParam = function ( param ) {
this.params.push( param );
if ( this.paramInputs[param] === undefined ) {
this.paramInputs[param] = new OO.ui.TextInputWidget( {} );
}
this.fieldset.addItems( [
new OO.ui.FieldLayout( this.paramInputs[ param ], {
label: '{{{' + param + '}}}',
align: 'left',
} ),
] );
};
LangPageLayout.prototype.removeParam = function ( param ) {
var index = this.params.indexOf( param );
if (index > -1) {
this.params.splice(index, 1);
this.fieldset.clearItems();
var self = this;
$.each( this.params, function(key, param) {
self.fieldset.addItems( [
new OO.ui.FieldLayout( self.paramInputs[ param ], {
label: '{{{' + param + '}}}',
align: 'left',
} ),
] );
} );
}
};
if ( mw.config.get( 'wgPageName' ) === 'User:Antoine_WMFr/AutotranslateHelper' && mw.config.get( 'wgAction' ) === 'view' ) {
ah = new AutotranslateHelper();
window.ah = ah;
}
});
//</nowiki>