Page MenuHomePhabricator

Investigation: Edit existing templates
Open, Needs TriagePublic5 Story Points

Description

It should be possible to open the TemplateWizard when the insertion point is in an existing template's wikitext, and be able to edit all parameters. Requested here, here and here.

Both the TemplateParamWizard gadget and Vorlagenmeister are able to do this with plain wikitext in the editor. However as soon as CodeMirror or wikEd is turned on, neither of them work as expected. They either fail to recognize the already inserted template or just don't work.

Questions for investigation:

  1. What's involved in parsing the template from a textarea? Can we offload this to Parsoid or reuse code from Vorlagenmeister/TemplateParamWizard?
  2. What are the potential pitfalls of doing this, if any?
  3. What's involved in making template parsing work with CodeMirror enabled?
    • Note that CodeMirror adds another "surface" to the editor. So maybe if we point to the right surface, we can parse the wikitext like normal.
  4. What's involved in making template parsing work with WikEd enabled?

Event Timeline

Samwilson created this task.Apr 9 2018, 2:47 AM
Restricted Application added a project: Community-Tech. · View Herald TranscriptApr 9 2018, 2:47 AM
Restricted Application added a subscriber: Aklapper. · View Herald Transcript
TBolliger added a subscriber: TBolliger.

Oh, very interesting idea. We should also think about how to signal to users that this is possible — maybe a state of the puzzle button in the toolbar?

Niharika renamed this task from Edit existing templates to Investigation: Edit existing templates.Apr 9 2018, 9:27 PM
Niharika updated the task description. (Show Details)
TBolliger set the point value for this task to 5.
Kipod added a subscriber: Kipod.EditedApr 13 2018, 10:51 PM

for your enjoyment, i copy the code that does the work on hewiki: - ~40 lines.

see https://he.wikipedia.org/wiki/Mediawiki:Gadget-TemplateParamWizard.js . below the code some elaboration, in case it's too cryptic. the wizard itself is outdated - it uses jquery ui, not the more modern/standard OOjs, and since it's inception predates templatedata, some other anachronisms.

for this reason, i would not recommend to take it "as is", but from a functional POV, it is still several degrees above and beyond the current mw wizard. it's not that long (~700 lines - about one fifth of the dewiki wizard), and you might want to go over it.

	function paramsFromSelection() {
		var selection = $("#wpTextbox1").textSelection('getSelection').replace(/^\s*\{\{|\}\}\s*$/g, ''); //scrap the first {{ and last }}
		var specials = [],
			match;
		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] || {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 ); 
			}
		}
	}

the first part, after getting the selection, is "folding" internal templates and internal links, storing original value in the "specials" array, and replacing it with "token", which is the stringified index index sandwiched between two null characters, assuming nulls never occur in actual text. this is done so the wizard understands that in {{template name | param1 = {{another template | all its params}} | param2 = [[File:name | thumb | schmumb | etc. ]] | param3 = [[ article | caption ]] }}, the "another template" in its entirety is just the value of param1, and won't get confused by all its | (or bars), and similarly for the file and internal link.

once this is done, the code assumes every single | denotes a parameter for this template. (will still get confused by html comments containing | . it wasn't a concern to us - we don;t have comments containing | inside templates, and if we do somewhere, we tolerate the breakage. if this is a concern, it should be easy enough to fold comments too)

next, each param is tested for '=', and if none found, it's replaced with <number>=param (see comment for "known bug". this can be fixed at complexity cost, but i decided this case is pathological enough, that i didn't really mind if the wizard will be incorrect for this case)

next, we split on '='. first item considered to be param name, the rest is re-joining with '=' as the value (so for | a = b = c, param name will be a, and value will be "b = c").

lastly, we unfold the tokes in the value, in reverse order.

this will still produce nonsense if the param name contains tokens, but it should not be real concern: if wiki code contains some pathology like | {{some template}} = some value, the wizard gets confused. luckily, hewiki does not contain such pathology, and hopefully no other wiki does. if any wiki does, not being able to use the wizard on the pathology does not look like a huge price to pay.

finally, the very end (everything after if ( /\n/.test( val ) )) handles special attribute supported by hewiki templates metadata syntax, but not by templatedata, and can be ignored (distinction betwixt single-line and multiline parameters, and #choice parameters).

peace.

@Kipod Thanks for the valuable information. Do you know if there is a way to make it work with wikEd or similar gadgets which modify the editor? That's the main concern we have from this task.

Kipod added a comment.EditedApr 16 2018, 3:12 PM

i believe we simply say "incompatible with wiked". wiked has a "disable" button[1], and the advice we give is, "disable wiked to use the wizard" (<s>i do believe</s> just tested, and the wizard works fine with wiked in a "disabled" state). disabling/enabling wiked is controlled by a single button on wiked toolbar, so it's not an onerous requirement. for hewiki this is not a major issue - relatively small number of editors on hewiki use wiked.

if wiked compatibility is a major issue, i'd recommend to find a way to hide the wizard's button when wiked is enabled (the opposite, i.e., disable wiked, seems less practical, since the order of operations is "select, then activate wizard", so by the time the user clicks the wizard, it's too late - disabling wiked at this point will drop the selection).

peace.

[1] actually, two: wiked's enable/disable button is duplicated: one in the toolbar, and one next to the "log out" linkette at the top of the screen.

Evad37 added a subscriber: Evad37.May 8 2018, 2:01 AM

In case its of interest, I've got a script that parses wikitext for templates: https://en.wikipedia.org/wiki/User:Evad37/rater.js (in the context of project banners on talk pages)
The regex I use is

config.regex = {
	// Pattern to find templates, which may contain other templates
	template:		/\{\{\s*(.+?)\s*(\|(?:.|\n)*?(?:(?:\{\{(?:.|\n)*?(?:(?:\{\{(?:.|\n)*?\}\})(?:.|\n)*?)*?\}\})(?:.|\n)*?)*|)\}\}\n?/g,
	// Pattern to find `|param=value` or `|value`, where `value` can only contain a pipe
	// if within square brackets (i.e. wikilinks) or braces (i.e. templates)
	templateParams:	/\|(?!(?:[^{]+}|[^\[]+]))(?:.|\s)*?(?=(?:\||$)(?!(?:[^{]+}|[^\[]+])))/g
};

The code to get templates from a page of wikitext is within Page.prototype.setTemplatesBanners; the code to extract the template name, and name:value pairs for parameters, is in Template.newFromRawWikitext and Template.makeParamsObject

Thanks @Evad37. We'll be sure to look into that when we get to doing this ticket (hopefully by next week).

TBolliger moved this task from Estimated to Product backlog on the Community-Tech board.

I'm dropping this for now because we have other higher priority stuff to do but we should complete this investigation at some point.

Change 459557 had a related patch set uploaded (by Eranroz; owner: Eranroz):
[mediawiki/extensions/TemplateWizard@master] Edit existing templates in TemplateWizard

https://gerrit.wikimedia.org/r/459557

eranroz claimed this task.Sep 10 2018, 2:15 PM

What's involved in parsing the template from a textarea? Can we offload this to Parsoid or reuse code from Vorlagenmeister/TemplateParamWizard?

What's involved in making template parsing work with CodeMirror enabled?

This code is based on TemplateParamWizard gadget, it works and tested in normal textarea (aka wpTextbox1) and have dependency for $.textSelection (getCaretPosition, getSelection, setSelection).
AFAIK CodeMirror is compatible with $.textSelection so it either works out of box or should be easily hook to work (I didn't directly tested it)

What's involved in making template parsing work with WikEd enabled?

$.textSelection is not fully compatible with wikEd, e.g selecting some text and pressing on Add Link button - doesn't use the selection in Wiked (compare to same with no Wiked).
I think getCaretPosition / getSelection doesn't work in it. However it should probably be valid to degrade gracefully.
I do see some support for $.textSelection in Wiked code (maybe @Cacycle can explain more about it), so maybe it is possible to make it work there too once those functions work in Wiked.

Mooeypoo added a subscriber: Mooeypoo.EditedSep 11 2018, 4:27 AM

Overall, the code looks good, (Thanks @eranroz for this!) but I have one concern that I think product/UX should consider (pinging @Niharika )

In the patch, we are assuming that we can trust the user to select a template. I am not very sure that's wise, but regardless of whether we should trust everyone to always mark the entire text or not (even on big multi-line templates, where you might miss a small selection piece) -- we need to decide what happens if that fails.

For example, say I have this template:

{{Test|user=foo}}

And say I select it, but my selection is partial (either by accident or on purpose) and so I have, in my selection, only this part: {{Test|user

The Wizard will believe the template is selected, so it will pre-load "Testing" template. It will recognize that there's a parameter and display it. In my test it displayed "user" inside the param value (this is likely a bug that needs fixing) but either way, I can then change the value to be whatever -- say, "mooeypoo" -- and then hit "insert". When I do, the insertion overrides my selected area, so I get this:

{{Test again|user=mooeypoo}}=foo}}

That's bad wikitext. Worse, ctrl-Z didn't work for me, I suspect because the way we override the text is not considered transactional for the textarea (different bug for a different day) -- but the point is that this is not really good behavior.

There are a couple of ways we can solve it, depending on UX/Product approach and technical difficulty:

  • Option A) Always expand the selection to encompass the entire template, if possible, and then load the wizard. This means that
    • 1. If the user is selecting nothing, but is INSIDE a template text, it will select the whole template. That means they won't be able to insert a template inside another template using the dialog; they'll have to insert the second template outside and copy/paste it in, if they so choose.
    • 2. If the user is inside a nested "inner" tempalte (template inside a template) the wizard's "expand to encompass template" may only recognize the inner template and not the outer one. That might be a good behavior... ?
  • Option B) If there's a partial selection, warn the user, and when the template is inserted, insert it after or before the template the user tried to select. This may be a little annoying to someone who meant to override a template -- but it will also make sure we're not inserting bad wikitext...

I'm a little worried that especially with complex templates (and ones that contain inner templates, which can go deeper and deeper) we will have a problem recognizing how to expand properly, so Option A may not be as straight forward or simple as it sounds... either way, I think we need to do something here, even if it's deciding we skip the edit (and instead insert before/after selection) if the template is invalid?

A couple of secondary comments:

  1. We should change the action button from "Insert" to "Edit" when a template is being edited.
  2. What happens if I edit a template, but then I click the "trash" button and choose another, and insert it? Right now with the current commit, it will replace the template. That sounds perfectly fine to me, but it can make things more destructive for the problem above (partial selection) if that's not intended.

@Mooeypoo Thank you for opening this discussion about selection. I think trusting the user selection is consistent with other tools of image/link but it is good idea to rethink about it because templates unlike links/images can be much more complex and the you have good points above.

Regarding the example this is dependent on the TemplateData of the edited template. You assume Template:Test have 1 unnamed parameter, and this is parsed (I think correctly) as "user" value rather than "user" parameter - based on the selection. If the template doesn't have templatedata of unnamed parameter, it will drop "user".

Regarding undo - tracked in T33780 and related to $.textSelection behavior.

@Kipod , @IKhitron , @PerfektesChaos - How does hewiki TemplateWizard and Vorlagenmeister handle inner templates and selection, and how do you think based on your experience it should work?

Thanks for calling me, but I'm the wrong person to ask this - I do not work with this wizard.
But I agree you should not spend your time on wikEd compatibility. The wikEd gadget has a lot of problems, and I see many complains that it destroys either interface or pages wikicode. Avoiding common work of these two tools is indeed a good idea.

Vorlagenmeister will open the nearest template around cursor (next template name / opening brackets to the left) and will show inner templates as plain wikitext.

  • From the left edge, beginning with the name, the right edge (terminating brackets at same level) is searched, considering HTML comments and nowiki. Fields at same level will be assigned by name and value on the way.
  • Since it is a development of 2009, nobody would complain on wikitext parameter values. Old fellows are used to wikitext.
  • To deal with inner template, just save and reopen at desired inner cursor position.

I am not really aware of this wizard here, and I was a bit surprised when I happened to pick this development, since I expected VE and its 2017 source mode to be the only successor.

For VE I would expect that VE should open a new instance of VE within the template editing form. Fields are supposed to be type:"content", but might be type:"string" and even type:"line". If content, or detected things like multiple apostroph, URL, tag, or multiple brackets, the field input should switch from plain input mode to markup input mode. Also complex values like bulleted/numbered list and table could appear and can be guessed more or less safely. Finally, a plain/rich mode switch should be accessible at least for unknown and suspicious fields, while boolean and numbers and URL should not be subject to markup (TemplateData available for judgement).

  • From my expectation VE should be able to edit a template transclusion within a template parameter value. If clicked, the current template editing form should be pushed on stack and a new instance of template editing form will show up, at the same position on screen, now editing the inner transclusion. Again a template transclusion can and will appear in some parameter values; therefore unlimited stacking is required. The inner forms might change values or get closed unchanged again until top level (article) is reached.
  • Markup and insertion controls shall be available while rich field is edited, and shall affect the current input area rather than top page level.
  • General input fields are supposed to be run in three modes: plain, visual, source. Plain goes for coded data which must not be contaminated by markup, and cannot be changed to visual. Imagine an URL or a number. However, the URL might be clicked as well as a page or file name. On the other hand, visual and source can be toggled, and source is actually the same as plain.

Development of Vorlagenmeister has been terminated more or less, by the way, and will receive minor efforts only as long as meaningful to be kept alive, but will not competite with VE/2017. Neither wikEd nor CodeMirror support is in the pipeline, but young tools like lintHint can do today.

None of Vorlagenmeister legacy code is recommended to be reused any more; the concept of 2009 has been refactored but would not stand future challenges.

I experienced wikEd support in three tools and also CodeMirror mode in two of those. It is no big deal. Just retrieve wikitext, and send back when leaving. Cursor position and selection are transparent, at least for CodeMirror. No disabling needed. Just detect whether one of them is currently activated; both cannot be on top.

If you have access to parsoid document model I would recommend to exploit that one. Template syntax with pipes within [[links]] and ignored syntax within <nowiki> and <syntaxhighlight> and <pre> and <!----> and, last but not least, <templatedata> spans and eternal nesting is a tricky exercise.

@eranroz @Mooeypoo For comparison, here's the behavior of the existing gadgets I see:

TemplateParamWizard:
  • If the cursor is placed within an existing template and the wizard button is clicked, the wizard pre-populates with text from the template.
  • If the entire template is selected, and the wizard button is clicked, the wizard pre-populates with text from the template.
Vorlagenmeister (TemplateMaster):
  • If the cursor is placed within an existing template and the wizard button is clicked, the wizard pre-populates with text from the template.
  • If the selected text lies entirely within a single template, and the wizard button is clicked, the wizard pre-populates with text from the template.
  • If the majority of the selected text lies within a single template, and the wizard button is clicked, the wizard pre-populates with text from the template.
  • If the majority of the selected text lies outside a template, the wizard asks for a confirmation on whether the user wants to use that template.
  • If the selected text contains multiple templates, the wizard asks for a confirmation on which template to use, if any. This functionality seems to be a bit broken currently.

(@PerfektesChaos beat me to this. Their description will be more accurate.)

Based on that and reading through the above discussion, I am inclined to go with a combination of TemplateParamWizard and @Mooeypoo's Option A. Here are the assumptions I see we can make:

Assumptions:
  • If the user places the cursor within a template, they may want to update the template they're in (including nested templates) or add a new inner/nested template.
  • If the user completely selects a single template, the user intentionally did that and wants to edit that template or replace that template with a new template.
  • If the user selects any other text (including partial or multiple templates or template+normal text), the user intends to replace that text by a new template.
Behavior:
  • If the cursor is placed within an existing template and the wizard button is clicked, the wizard pre-populates with text from the template.
    • If the user edits the template and inserts it, the template on the page is updated.
    • If the user deletes the template and adds a new one, the new template gets inserted where the cursor was.
  • If an entire template is selected, and the wizard button is clicked, the wizard pre-populates with text from the template.
    • If the user edits the template and inserts it, the template on the page is updated.
    • If the user deletes the template and adds a new one, the new template replaces the one that was on the page.
    • This remains true for inner/nested templates.
  • If the user selects any other text (incomplete template OR multiple templates OR template+outside text), we don't pre-populate the template and allow the user to add a new template.

@eranroz @Mooeypoo @Kipod @PerfektesChaos Thoughts on this? I will also run this by the community on the project page after.

Well, selection of a region is actually not recommended. Ideally it is cursor position only with no selection span. If there is a span, yes, it might become disambiguous. One existing template transclusion only shall be identified, best in name span, and the current values are supposed to prefill the form. Otherwise a new transclusion might be inserted.

If cursor is in parameter value span a new template might be inserted into that parameter value.

thanks, @Niharika , this is super useful.

Assumptions:
  • If the user places the cursor within a template, they may want to update the template they're in (including nested templates) or add a new inner/nested template.
  • If the user completely selects a single template, the user intentionally did that and wants to edit that template or replace that template with a new template.
  • If the user selects any other text (including partial or multiple templates or template+normal text), the user intends to replace that text by a new template.

If we go by these assumptions, I think we should, technically, expand the selection to wrap the template the user's in context of.

So to expand on the behavior:

Behavior:
  • If the cursor is placed within an existing template and the wizard button is clicked, the wizard pre-populates with text from the template.
    • If the user edits the template and inserts it, the template on the page is updated.
    • If the user deletes the template and adds a new one, the new template gets inserted where the cursor was.
  • If an entire template is selected, and the wizard button is clicked, the wizard pre-populates with text from the template.
    • If the user edits the template and inserts it, the template on the page is updated.
    • If the user deletes the template and adds a new one, the new template replaces the one that was on the page.
    • This remains true for inner/nested templates.
  • If the user selects any other text (incomplete template OR multiple templates OR template+outside text), we don't pre-populate the template and allow the user to add a new template.

Okay, but then where do we add the template? Do we override the selection, even if it's partial? It sounds to me like a recipe for big problems, so here's my suggestion:

  • If the user is inside a template -- be it just the cursor, or any partial selection or full selection
    • The wizard first expands the selection to cover the full template the cursor is in, and then loads the dialog for editing.
  • If the user selected text that is not a template
    • We collapse the selection to be either above or below the selection
    • We start the wizard in "new template" mode
    • This means that when we insert, we don't mangle anything

What we gain with that:

  • Clarity for the user of what the dialog is editing and where the wikitext produces is going to actually be at the end
  • Preventing the "clearer" paths of mangling data after insertion by partial selections
  • In the second case (not template or multiple templates, where we collapse) we air on the side of caution; it might be that the user intended to delete the text they selected, but because it's unclear, I think it's preferable that we don't do that for them -- they can always delete the text they wanted to replace afterwards, which is better than us deleting it for them without a chance to undo.

I think it's worth it for us to be careful, and expanding/collapsing the selection may be slightly more complex but shouldn't be terrible, so it sounds to me to be a good balance of effort vs. gain to the user.

@Niharika, this goes according to the assumptions you wrote, and just slightly expands on them. Does this sound good? @eranroz what do you think about this?

Well, selection of a region is actually not recommended. Ideally it is cursor position only with no selection span. If there is a span, yes, it might become disambiguous. One existing template transclusion only shall be identified, best in name span, and the current values are supposed to prefill the form. Otherwise a new transclusion might be inserted.
If cursor is in parameter value span a new template might be inserted into that parameter value.

I don't know if we can identify this fully right now (being inside a parameter vs. generally in a template), and I think we have a lot more risk of people not quite understanding that they'll always add a template if they're in that state. We can perhaps explore that.

I think it's a good compromise that we always edit the template in this case. If the user intentionally wants a template inside a template (which is advanced) they can insert the barebone template manually (just its name) and then, according to my plan above, if the cursor is inside the inner template, the selection will expand to the inner template only, the dialog will open in "edit" mode, and the user can add parameters to it without mangling or changing the surrounding wikitext.

I think this is a good compromise that gives a good user experience while being reasonable technically.

  • If the user is inside a template -- be it just the cursor, or any partial selection or full selection
    • The wizard first expands the selection to cover the full template the cursor is in, and then loads the dialog for editing.

Sounds good. We already do it based on the cursor (e.g no selection) so it will make it consistent also with selection (and this easy to code :) )

  • If the user selected text that is not a template
    • We collapse the selection to be either above or below the selection

I think we can do it similar to VE - just after the selection.

thanks, @Niharika , this is super useful.

Assumptions:
  • If the user places the cursor within a template, they may want to update the template they're in (including nested templates) or add a new inner/nested template.
  • If the user completely selects a single template, the user intentionally did that and wants to edit that template or replace that template with a new template.
  • If the user selects any other text (including partial or multiple templates or template+normal text), the user intends to replace that text by a new template.

If we go by these assumptions, I think we should, technically, expand the selection to wrap the template the user's in context of.
So to expand on the behavior:

Behavior:
  • If the cursor is placed within an existing template and the wizard button is clicked, the wizard pre-populates with text from the template.
    • If the user edits the template and inserts it, the template on the page is updated.
    • If the user deletes the template and adds a new one, the new template gets inserted where the cursor was.
  • If an entire template is selected, and the wizard button is clicked, the wizard pre-populates with text from the template.
    • If the user edits the template and inserts it, the template on the page is updated.
    • If the user deletes the template and adds a new one, the new template replaces the one that was on the page.
    • This remains true for inner/nested templates.
  • If the user selects any other text (incomplete template OR multiple templates OR template+outside text), we don't pre-populate the template and allow the user to add a new template.

Okay, but then where do we add the template? Do we override the selection, even if it's partial? It sounds to me like a recipe for big problems, so here's my suggestion:

  • If the user is inside a template -- be it just the cursor, or any partial selection or full selection
    • The wizard first expands the selection to cover the full template the cursor is in, and then loads the dialog for editing.

This sounds fine to me but there's still the open question of what do we do when we prepopulate the wizard and then the user hits the Trash button and creates another template. Do we insert the new template or replace the original one?

  • If the user selected text that is not a template
    • We collapse the selection to be either above or below the selection

I'm not clear on what you mean by this. Can you expand a bit?

  • We start the wizard in "new template" mode
  • This means that when we insert, we don't mangle anything

What we gain with that:

  • Clarity for the user of what the dialog is editing and where the wikitext produces is going to actually be at the end
  • Preventing the "clearer" paths of mangling data after insertion by partial selections
  • In the second case (not template or multiple templates, where we collapse) we air on the side of caution; it might be that the user intended to delete the text they selected, but because it's unclear, I think it's preferable that we don't do that for them -- they can always delete the text they wanted to replace afterwards, which is better than us deleting it for them without a chance to undo.

I think it's worth it for us to be careful, and expanding/collapsing the selection may be slightly more complex but shouldn't be terrible, so it sounds to me to be a good balance of effort vs. gain to the user.
@Niharika, this goes according to the assumptions you wrote, and just slightly expands on them. Does this sound good? @eranroz what do you think about this?

Some of this goes against the last assumption but I think it's okay to be more cautious. Here's my summary of what you are suggesting we do -

  • User selects text that's either a full template or any part of a template's body
    • Prepopulate the wizard with the immediate template surrounding the selection
  • User selects anything else
    • Give user a blank wizard and insert template at the end of selection
  • User places cursor inside a template
    • Prepopulate the wizard with the immediate template surrounding the cursor position

Does that sound like what you were suggesting?

This sounds fine to me but there's still the open question of what do we do when we prepopulate the wizard and then the user hits the Trash button and creates another template. Do we insert the new template or replace the original one?

Replace the original (user explicitly pressed on trash button)

  • If the user selected text that is not a template
    • We collapse the selection to be either above or below the selection

I'm not clear on what you mean by this. Can you expand a bit?

Same as VE - text is added just after the selection

This sounds fine to me but there's still the open question of what do we do when we prepopulate the wizard and then the user hits the Trash button and creates another template. Do we insert the new template or replace the original one?

Replace the original (user explicitly pressed on trash button)

What if the user never intended to modify a template but instead to add a nested template? We'll be forcing them to delete the template they placed the cursor in.

  • If the user selected text that is not a template
    • We collapse the selection to be either above or below the selection

I'm not clear on what you mean by this. Can you expand a bit?

Same as VE - text is added just after the selection

Got it, thanks.

The more I think about the selection behavior, the more complex it appears to be. For example, the collapse template on enwiki can take a lot of text. See example on top of https://en.wikipedia.org/wiki/Template:Collapse. Say the wikitext is:

{{collapse|Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Curabitur pretium tincidunt lacus. Nulla gravida orci a odio. Nullam varius, turpis et commodo pharetra, est eros bibendum elit, nec luctus magna felis sollicitudin mauris. Integer in mauris eu nibh euismod gravida. Duis ac tellus et risus vulputate vehicula. Donec lobortis risus a elit. Etiam tempor. Ut ullamcorper, ligula eu tempor congue, eros est euismod turpis, id tincidunt sapien risus a quam. Maecenas fermentum consequat mi. Donec fermentum. Pellentesque malesuada nulla a mi. Duis sapien sem, aliquet nec, commodo eget, consequat quis, neque. Aliquam faucibus, elit ut dictum aliquet, felis nisl adipiscing sapien, sed malesuada diam lacus eget erat. Cras mollis scelerisque nunc. Nullam arcu. Aliquam consequat. Curabitur augue lorem, dapibus quis, laoreet et, pretium ac, nisi. Aenean magna nisl, mollis quis, molestie eu, feugiat in, orci. In hac habitasse platea dictumst.

Fusce convallis, mauris imperdiet gravida bibendum, nisl turpis suscipit mauris, sed placerat ipsum urna sed risus. In convallis tellus a mauris. Curabitur non elit ut libero tristique sodales. Mauris a lacus. Donec mattis semper leo. In hac habitasse platea dictumst. Vivamus facilisis diam at odio. Mauris dictum, nisi eget consequat elementum, lacus ligula molestie metus, non feugiat orci magna ac sem. Donec turpis. Donec vitae metus. Morbi tristique neque eu mauris. Quisque gravida ipsum non sapien. Proin turpis lacus, scelerisque vitae, elementum at, lobortis ac, quam. Aliquam dictum eleifend risus. In hac habitasse platea dictumst. Etiam sit amet diam. Suspendisse odio. Suspendisse nunc. In semper bibendum libero.}}
  • Case 1: If someone wants to add a template after the second paragraph, they can place the cursor there and activate the wizard. The wizard prepopulates with the collapse template, which baffles the user for a second but they realize what happened and hit the Trash button because they never intended to replace the collapse template. They then add the template they wanted and insert it. It inserts at the cursor position and does not replace the collapse template.
  • Case 2: If someone wants to replace the sentence In hac habitasse platea dictumst. by a template, they select the sentence and activate the wizard. The wizard prepopulates with the collapse template. The user hits the trash button because they never intended to replace the collapse template. They then add the template they wanted and insert it. It replaces the selected sentence.

@Mooeypoo @eranroz Does this behavior make sense?

Well, that is why I

  • distinguish between
    • the parameter value span (or top level out of any template)
    • any other point of the template transclusion
  • prefer cursor position with no selection range.

That makes expected behaviour much more predictable and easier to understand for end users.

  • There are unambiguos cases of selected regions, but in general it opens more questions what a user request to be done.
  • It might be intended that the selected region is to be enclosed as first unnamed parameter within a chosen template. Who knows? There are a lot of formatting templates supporting that.
  • The user might not be aware that there is more than one complete template transclusion in selection range. Which one is meant?