TemplateScript: Difference between revisions

From Meta, a Wikimedia project coordination wiki
Content deleted Content added
update examples, tweak documentation, use more compressed format when readable
updated examples
Line 41: Line 41:
// <pre>
// <pre>
$.ajax('//tools-static.wmflabs.org/meta/scripts/pathoschild.templatescript.js', { dataType:'script', cache:true }).then(function() {
$.ajax('//tools-static.wmflabs.org/meta/scripts/pathoschild.templatescript.js', { dataType:'script', cache:true }).then(function() {
pathoschild.TemplateScript.Add([
pathoschild.TemplateScript.add([
// add your own templates or scripts here
// add your own templates or scripts here
{ name: 'welcome', template: '{{subst:welcome}} ~~~~', position: 'after', editSummary: 'welcome!', forNamespaces: 3, forActions: 'edit' },
{ name: 'welcome', template: '{{subst:welcome}} ~~~~', position: 'after', editSummary: 'welcome!', forNamespaces: 3, forActions: 'edit' },
Line 54: Line 54:
You define templates and scripts by passing a <code>[[#Template|Template]]</code>-like object to the <code><span style="color:gray;">pathoschild.TemplateScript.</span>Add()</code> function. Here's an example of several <code>Template</code> options. This will create a new sidebar box with the header "<tt>Being nice</tt>", with a link named "<tt>Welcome</tt>" — but only if you're editing a user's talk page (''forNamespaces''). When you click the link, it will insert "<tt><nowiki>{{subst:welcome}} ~~~~</nowiki></tt>" at the end of the edit box, and set the edit summary to "<tt>Welcome!</tt>".
You define templates and scripts by passing a <code>[[#Template|Template]]</code>-like object to the <code><span style="color:gray;">pathoschild.TemplateScript.</span>Add()</code> function. Here's an example of several <code>Template</code> options. This will create a new sidebar box with the header "<tt>Being nice</tt>", with a link named "<tt>Welcome</tt>" — but only if you're editing a user's talk page (''forNamespaces''). When you click the link, it will insert "<tt><nowiki>{{subst:welcome}} ~~~~</nowiki></tt>" at the end of the edit box, and set the edit summary to "<tt>Welcome!</tt>".
<source lang="javascript">
<source lang="javascript">
pathoschild.TemplateScript.Add({
pathoschild.TemplateScript.add({
category: 'Being nice',
category: 'Being nice',
name: 'Welcome',
name: 'Welcome',
Line 66: Line 66:
You can also add many templates at once:
You can also add many templates at once:
<source lang="javascript">
<source lang="javascript">
pathoschild.TemplateScript.Add([
pathoschild.TemplateScript.add([
{
{
category: 'Being nice',
category: 'Being nice',
Line 88: Line 88:
If your templates repeat some fields, you can add the common fields once as a second argument. For example, this code is equivalent to the last example:
If your templates repeat some fields, you can add the common fields once as a second argument. For example, this code is equivalent to the last example:
<source lang="javascript">
<source lang="javascript">
pathoschild.TemplateScript.Add(
pathoschild.TemplateScript.add(
[
[
{ name:'Welcome', template:'{{subst:welcome}} ~~~~', editSummary:'Welcome!' },
{ name:'Welcome', template:'{{subst:welcome}} ~~~~', editSummary:'Welcome!' },
Line 263: Line 263:
<li>A simple template and a simple script:
<li>A simple template and a simple script:
<source lang="javascript">
<source lang="javascript">
pathoschild.TemplateScript.Add([
pathoschild.TemplateScript.add([
{
{
name: 'header',
name: 'header',
Line 284: Line 284:
<li>A combination template and script:
<li>A combination template and script:
<source lang="javascript">
<source lang="javascript">
pathoschild.TemplateScript.Add({
pathoschild.TemplateScript.add({
name: 'current URL',
name: 'current URL',
template: '<$URL>',
template: '<$URL>',
Line 296: Line 296:
<source lang="javascript">
<source lang="javascript">
/* editing pages */
/* editing pages */
pathoschild.TemplateScript.Add(
pathoschild.TemplateScript.add(
[
[
/* main namespace */
/* main namespace */
Line 331: Line 331:


/* deleting pages */
/* deleting pages */
pathoschild.TemplateScript.Add(
pathoschild.TemplateScript.add(
[
[
{ name: 'Copyvio discussion', template: '[[WS:COPYVIO|Possible copyright violation]]' },
{ name: 'Copyvio discussion', template: '[[WS:COPYVIO|Possible copyright violation]]' },
Line 359: Line 359:


/* various forms */
/* various forms */
pathoschild.TemplateScript.Add([
pathoschild.TemplateScript.add([
{
{
forActions: 'protect',
forActions: 'protect',
Line 399: Line 399:
*/
*/
$.getScript('//tools.wmflabs.org/meta/scripts/pathoschild.templatescript.js', function() {
$.getScript('//tools.wmflabs.org/meta/scripts/pathoschild.templatescript.js', function() {
pathoschild.TemplateScript.Add([
pathoschild.TemplateScript.add([
{ category: 'Amazing Gadget', name: 'Do cool stuff', script: function() { MyGadget.DoStuff(); } }
{ category: 'Amazing Gadget', name: 'Do cool stuff', script: function() { MyGadget.DoStuff(); } }
]);
]);

Revision as of 14:41, 10 May 2015

TemplateScript is a powerful user script framework for adding custom one-click templates and scripts to your sidebar. Essentially:

  1. create templates (bits of text that can be inserted wherever you choose) or scripts (bits of JavaScript code that are executed);
  2. choose when they appear — always (even when reading), by namespace, action (like 'edit' or 'move'), or arbitrary conditions;
  3. click the sidebar link (or press the keyboard shortcut) to instantly insert your custom template or run your custom script.

It's compatible with all Wikimedia skins and common browsers.

Introduction

When you first install TemplateScript, you should see a new navigation box labeled 'TemplateScript' at the bottom of your sidebar. (This is the default — you can add as many new links or navigation boxes you want.)

You can click the 'Regex editor' link to activate that example script. This tool lets you apply any number of regular expressions to the text, and save them for later use. For example, you could define a series of changes to close a request or update a template, then save those steps and apply them to any other page later. The regex editor looks like this:

The regex editor is just an example of what you can do — TemplateScript is really meant for you to create your own scripts and templates. A template is really just a bit of text that gets added to the page when you click on it (you can choose where it gets added). A script is a bit of JavaScript that gets run when you click its link, so you can do anything (the regex editor is just a script). You can also assign keyboard shortcuts to templates or scripts to use them more quickly.

The easiest way to get started is to copy the 'welcome' example from the installation sample code, and change the name and text. To really delve in, you can read the documentation below.

Usage

Installation

  1. Copy the following code to your global.js page (for all wikis) or your common.js page (for Meta only).
    • If you just want to use the regex editor:
      /**
       * TemplateScript adds configurable templates and scripts to the sidebar, and adds an example regex editor.
       * @see https://meta.wikimedia.org/wiki/TemplateScript
       * @update-token [[File:pathoschild/templatescript.js]]
       */
      mw.loader.load('//tools-static.wmflabs.org/meta/scripts/pathoschild.templatescript.js');
      
    • Or if you want to use custom scripts and templates:
      /**
       * TemplateScript adds configurable templates and scripts to the sidebar, and adds an example regex editor.
       * @see https://meta.wikimedia.org/wiki/TemplateScript
       * @update-token [[File:pathoschild/templatescript.js]]
       */
      // <pre>
      $.ajax('//tools-static.wmflabs.org/meta/scripts/pathoschild.templatescript.js', { dataType:'script', cache:true }).then(function() {
      	pathoschild.TemplateScript.add([
      		// add your own templates or scripts here
      		{ name: 'welcome', template: '{{subst:welcome}} ~~~~', position: 'after', editSummary: 'welcome!', forNamespaces: 3, forActions: 'edit' },
      	]);
      });
      // </pre>
      
  2. Refresh your browser to reload the JavaScript. (In Chrome or Firefox, press [CTRL] and [R] at the same time.)

Creating templates

You define templates and scripts by passing a Template-like object to the pathoschild.TemplateScript.Add() function. Here's an example of several Template options. This will create a new sidebar box with the header "Being nice", with a link named "Welcome" — but only if you're editing a user's talk page (forNamespaces). When you click the link, it will insert "{{subst:welcome}} ~~~~" at the end of the edit box, and set the edit summary to "Welcome!".

pathoschild.TemplateScript.add({
	category: 'Being nice',
	name: 'Welcome',
	template: '{{subst:welcome}} ~~~~',
	position: 'after',
	editSummary: 'Welcome!',
	forNamespaces: 3
});

You can also add many templates at once:

pathoschild.TemplateScript.add([
	{
		category: 'Being nice',
		name: 'Welcome',
		template: '{{subst:welcome}} ~~~~',
		position: 'after',
		editSummary: 'Welcome!',
		forNamespaces: 3
	},
	{
		category: 'Being nice',
		name: 'Hi',
		template: '{{subst:hi}} ~~~~',
		position: 'after',
		editSummary: 'Hi!',
		forNamespaces: 3
	}
]);

If your templates repeat some fields, you can add the common fields once as a second argument. For example, this code is equivalent to the last example:

pathoschild.TemplateScript.add(
	[
		{ name:'Welcome', template:'{{subst:welcome}} ~~~~', editSummary:'Welcome!' },
		{ name: 'Hi', template:'{{subst:hi}} ~~~~', editSummary:'Hi!' }
	],
	{ category:'Being nice', position:'after', forNamespaces:3 } // common fields
);

See Template for a full list of options you can pass.

Template objects

Template
The pathoschild.TemplateScript.Template object contains all the options for a template or script. You must specify a name and template (or script), but all other fields are optional.
User interface and enabling:
option type default value purpose
name string (required) The name displayed as the sidebar link text.
enabled boolean true Whether this template is available.
category string 'TemplateScript' An arbitrary category name (for grouping templates into multiple sidebars), or null to use the default sidebar.
forActions string or string[] (all actions) The wgAction values for which the template is enabled.
forNamespaces int or int[] (all namespaces) The namespaces in which the template is enabled.
accessKey string none A keyboard shortcut that will instantly apply the template or script. This should be a single key like 'x' or '1', which will be combined with your browser's shortcut sequence (for example, in Chrome you'd press ALT+x). See w:Wikipedia:Keyboard shortcuts for your browser's keyboard shortcut sequence.
tooltip string none A short explanation of the template or script, typically shown when you hover your cursor over the link.
Behaviour:
option type default value purpose
template string null The text to insert into the main input box.
position string 'cursor'
or 'replace'
The position at which to insert the template. The default value is 'cursor' when editing a page, and 'replace' in all other cases.
isMinorEdit boolean false Whether to mark the edit as minor (if applicable).
editSummary string null The edit summary to use (if applicable).
editSummaryPosition string 'replace' The position at which to insert the edit summary.
headline string null The subject or headline to use (if applicable). This appears when editing a page with &section=new in the URL.
headlinePosition string 'replace' The position at which to insert the headline.
Scripting:
option type default value purpose
autoSubmit boolean false Whether to submit the form automatically after insertion.
script function null An arbitrary JavaScript function that is called after the template and edit summary are applied, but before autoSubmit. It is passed a reference to the Context object.
Position
The pathoschild.TemplateScript.Position values represent the insertion behaviour. These can be specified either as a constant (pathoschild.TemplateScript.Position.cursor) or by name ('cursor').
value meaning
before Insert before the text.
after Insert after the text.
cursor Insert the template at the current cursor position (replacing the selected text, if any).
replace Replace the current text entirely.
Context
The pathoschild.TemplateScript.Context object provides convenient access to properties about the current page. This is passed to Template scripts. (This object is populated by TemplateScript; changing the values yourself may cause unexpected behaviour.)
value type meaning
namespace int The number of the current namespace.
action string The current MediaWiki action.
singleton pathoschild.TemplateScript The TemplateScript instance for the page.
$target jQuery The primary input element (e.g., the edit textarea) for the current form.
$editSummary jQuery The edit summary input element (if relevant to the current form).

Examples

  • A simple template and a simple script:
    pathoschild.TemplateScript.add([
    	{
    		name: 'header',
    		template: '{{header | some parameter = true }}',
    		position: 'before',
    		editSummary: 'added {{header}}',
    		forNamespaces: 0,
    		forActions: 'edit'
    	},
    	{
    		name: 'alert test',
    		script: function ($target) {
    			alert('The edit box says: "' + $target.val() + '".');
    		},
    		forActions: 'edit'
    	}
    ]);
    
  • A combination template and script:
    pathoschild.TemplateScript.add({
    	name: 'current URL',
    	template: '<$URL>',
    	script: function (context) {
    		context.$target.val(context.$target.val().replace(/<\$URL>/g, location.href));
    	}
    });
    
  • A more comprehensive example the English Wikisource, with page header templates and summaries for deletion, moving, and protection (only shown when relevant):
    /* editing pages */
    pathoschild.TemplateScript.add(
    	[
    		/* main namespace */
    		{
    			name: 'header',
    			template: '{{header\n | title    =\n | author   =\n | section  =\n | previous =\n | next     =\n | notes    =\n}}',
    			position: 'before',
    			forNamespaces: 0
    		},
    		
    		/* talk namespace */
    		{
    			name: 'featured talk',
    			template: '{{featured talk\n | month   = {{subst:CURRENTMONTH}}\n | year    = {{subst:CURRENTYEAR}}\n | archive = {{subst:CURRENTYEAR}}/{{subst:CURRENTMONTH}}\n}}',
    			forNamespaces: 1
    		},
    		{
    			name: 'textinfo',
    			template: '{{textinfo\n| edition      =\n| source       =\n| contributors =\n| progress     =\n| notes        =\n| proofreaders =\n}}',
    			position: 'before',
    			editSummary: '{{textinfo}}',
    			forNamespaces: 1
    		},
    		
    		/* author namespace */
    		{
    			name: 'author',
    			template: '{{author\n |name           =\n |last_initial   =\n |dates          =\n |description    =\n |image          =\n |wikipedia_link =\n |wikiquote_link =\n |commons_link   =\n}}',
    			forNamespaces: 102
    		}
    	],
    	{ forActions: 'edit' } // common fields
    );
    
    /* deleting pages */
    pathoschild.TemplateScript.add(
    	[
    		{ name: 'Copyvio discussion', template: '[[WS:COPYVIO|Possible copyright violation]]' },
    		{ name: 'Proposed', template: '[[WS:DEL|Proposed deletion]]' }
    		{ name: 'G1 no meaningful', template: '[[WS:CSD|Criteria for speedy deletion]] G1 ("No meaningful content or history.")' },
    		{ name: 'G2 recreation', template: '[[WS:CSD|Criteria for speedy deletion]] G2 ("Reposted content previously deleted...")' },
    		{ name: 'G3 banned user', template: '[[WS:CSD|Criteria for speedy deletion]] G3 ("content created and edited solely by a banned user after they were banned...")' },
    		{ name: 'G4 redundant', template: '[[WS:CSD|Criteria for speedy deletion]] G4 ("Two versions of the same text on different pages...")' },
    		{ name: 'G5 beyond scope', template: '[[WS:CSD|Criteria for speedy deletion]] G5 ("...clearly lies outside the [[WS:WWI|scope of Wikisource]]...")' },
    		{ name: 'G6 copyvio', template: '[[WS:CSD|Criteria for speedy deletion]] G6 ("...clear and proven copyright violation...")' },
    		{ name: 'G6 re-copyvio', template: '[[WS:CSD|Criteria for speedy deletion]] G6 ("...content previously deleted as a copyright violation...")' },
    		{ name: 'G6 copyvio author', template: '[[WS:CSD|Criteria for speedy deletion]] G6 ("...author pages for authors whose works are all copyrighted...")' },
    		{ name: 'G7 author\'s request', template: '[[WS:CSD|Criteria for speedy deletion]] G7 ("Deletion per request of the author...")' },
    		{ name: 'A1 transwikied', template: '[[WS:CSD|Criteria for speedy deletion]] A1 ("Articles [[m:transwiki|transwikied]] to another project...")' },
    		{ name: 'A1 transwikied (commons)', template: '[[WS:CSD|Criteria for speedy deletion]] A1 ("...images uploaded to the [[commons:|Wikimedia commons]] with the original contributor noted...")' },
    		{ name: 'A2 non-notable', template: '[[WS:CSD|Criteria for speedy deletion]] A2 ("...not significantly peer-reviewed or previously published in a significant edition or forum.")' },
    		{ name: 'A3 no authorship info', template: '[[WS:CSD|Criteria for speedy deletion]] A3 ("Works without authorship information...")' },
    		{ name: 'M1 trivial', template: '[[WS:CSD|Criteria for speedy deletion]] M1 ("...deletion as part of a page move or history merge, as long as the action requiring the deletion is uncontroversial.")' },
    		{ name: 'M2 redirect (new)', template: '[[WS:CSD|Criteria for speedy deletion]] M2 ("Unneeded redirects from page titles created within the last week...")' },
    		{ name: 'M2 redirect (old)', template: '[[WS:CSD|Criteria for speedy deletion]] M2 ("...[unneeded] redirects tagged with {{subst:dated soft redirect|"[[new title]]"}} for at least two months.")' },
    		{ name: 'M2 redirect (broken)', template: '[[WS:CSD|Criteria for speedy deletion]] M2 ("...Redirects to inexistant pages...)"' },
    		{ name: 'M3 redirect (article to other ns)', template: '[[WS:CSD|Criteria for speedy deletion]] M3 ("Internamespace redirects from the article namespace to any other namespace.")' },
    		{ name: 'M4 talk page', template: '[[WS:CSD|Criteria for speedy deletion]] M4 ("Unneeded talk: a discussion page for deleted or inexistant content.")' }
    	],
    	{ forActions: 'delete', category: 'Deletion reasons' } // common fields
    );
    
    /* various forms */
    pathoschild.TemplateScript.add([
    	{
    		forActions: 'protect',
    		name: 'featured',
    		template: '[[WS:FT|Featured text]] (see the [[WS:PP|protection policy]])',
    		position: 'replace'
    	},
    	{
    		forActions: 'move',
    		name: 'standardized',
    		template: '[[WS:STYLE|Standardised]]',
    		position: 'replace'
    	}
    ]);
    

Troubleshooting

  1. If something isn't working, open your browser's JavaScript window and look for errors or warnings that might tell you something is wrong.
  2. Don't use $element.text() or $element.html() to edit input boxes.
    Always use $element.val() to change input box content. The $element.text() or $element.html() methods modify the element HTML directly, not the current value — these will cause the user's changes to be lost.

Regex editor

TemplateScript includes a default tool called the regex editor (see live example), which lets you define any number of custom regular expressions and apply them to the text. You can disable this feature by adding the following code before TemplateScript:

var pathoschild = pathoschild || {};
pathoschild.disableRegexEditor = true;


As a gadget or framework

TemplateScript is designed to work well as a gadget (or even multiple gadgets). You can simply call it many times the same way, and it will smartly extend the first instance. This also makes it very suitable as a framework for your own scripts — it will take care of creating a navigation box and links for you, and the user can enable many similar gadgets and have all their tools neatly organised together.

Here's how to initialise an example script created using TemplateScript:

/**
 * Amazing Gadget does some pretty cool stuff.
 * @see https://example.com/amazing-gadget
 */
$.getScript('//tools.wmflabs.org/meta/scripts/pathoschild.templatescript.js', function() {
	pathoschild.TemplateScript.add([
		{ category: 'Amazing Gadget', name: 'Do cool stuff', script: function() { MyGadget.DoStuff(); } }
	]);
});

If you want your script to always be available (not only when editing or doing something), just leave out the options like forNamespace or forAction.

See also