//(This proposal was originally called "hygenic arguments"; easily confusable with a mostly-unrelated hygenic **templates** proposal. The latter are now ["balanced" templates](https://phabricator.wikimedia.org/T114445) and we're now calling this proposal "heredoc arguments".)//
As described in my [Wikimania 2015 talk](https://wikimania2015.wikimedia.org/wiki/Submissions/Templates_are_dead!_Long_live_templates!) ([starting at slide 31](https://wikimania2015.wikimedia.org/w/index.php?title=File:Templates_are_dead!_Long_live_templates!.pdf&page=31)), the existing template argument syntax offers a number of traps for the unwary (for example, with the characters `=`, `|`, etc). As a result, it is difficult to easily move large blocks of text into templates.
As a result, we often have constructs such as:
```
{{tablestart|class="shiny"}}
| Hello || wiki = world
{{tableend}}
```
which pose a number of issues:
# There is no mechanism to ensure `{{tablestart}}` and `{{tableend}}` are properly matched
# Both `{{tablestart}}` and `{{tableend}}` emit unbalanced HTML, which complicates work on efficiently updating the parser cache after template changes.
# Due to the tag matching issues, this whole block is uneditable by Visual Editor.
If we were to try to write a `{{table}}` template which accepted the contents as an argument, it would have to look like:
```
{{table|class="shiny"|
{{!}} Hello {{!}}{{!}} wiki = world
}}
```
Our arguments needed to be transformed in two different ways to prevent `|` and `=` from being mangled when we shoehorned them into a template argument. (You could also use `{{=}}`... but not `{{|}}`.)
This would also create dirty diffs inside the argument if all you wanted to do was wrap existing wikitext into a template parameter.
Consider also:
```
{{sectionstart}}
==heading==
{{sectionend}}
```
Properly escaping the heading to make it a valid template argument is non-trivialYou can't just use `<nowiki>=</nowiki>` around `=` characters, if you want that to work.
**Heredoc arguments** provide a new form of template invocation which avoids these issues.
The above examples would be written as:
```
{{<<T{{table|class="shiny"}}|<<<
| Hello || wiki = world
{{>> Table}}>>>}}
{{<<S{{section}}|<<<
==heading==
{{>>Section}}>>>}}
```
Named arguments (like `class` in this example) can be passed using `name=<<<...>>>`. The new `Template:Table` can now emit properly balanced HTML, with both `<table>` and `</table>` generated by the same template (instead of by two separate templates). Visual Editor can now edit this block as a single template invocation, invoking itself recursively to edit the template arguments as it does now.
The only special character in the argument when expressed this way is `>>>`. We'll support nesting `<<<....>>>`, since that's the common case where `>>>` would appear, and you could also use `<nowiki>>>></nowiki>`. However, we'll also provide a "tag" mechanism to ensure that *any* wikitext can be wrapped into a template argument with *zero dirty diffs inside the template argument*:
```
and the contents between the template start `{{<<...}}` and template end `{{>>...}}` are passed as (WLOG) the last positional argument of the template, after any existing positional arguments in the template start. Named arguments (like `class` in this example) can be passed using the existing argument syntax as before. The new `Template:Table` can now emit properly balanced HTML,{{{wrapper|arg=123<<<
This test can contain >>> it's fine!
>>>123}}}
```
The tag before the `<<<` can be any number. (WLOG it could be an alphanumeric tag, but latin alphabetic characters can play havoc in RTL contexts; with both `<table>` and `</table>` generated by the same template (instead of by two separate templates). Visual Editor can now edit this block as a single template invocationif we restrict to numeric tags we are guaranteed that RTL will look good.) It is always possible to choose a number `N` such that `>>>N` never appears in the argument (for example, N could have more digits than the argument has characters), invoking itself recursively to edit the template arguments as it does nowwhich means it is always possible to wrap arbitrary wikitext without making any internal changes to the wikitext.
Further, tThere are no special characters or odd escape rules in the argument when expressed this way. The only "special" construct inside the argument is `{{<<...}}` and any of those characters can be replaced by an html entity to allow that character sequence to be included literally if needed. That isWe don't need special `{{!}}`, we don't need special `{{!}}``{{=}}`, `{{=}}`,etc escapes; etc escapeswe won't have dirty diffs or require careful search-and-replace when wrapping wikitext.
Another example, from @brion's talk on [citations](https://wikimania2015.wikimedia.org/wiki/Submissions/Future_of_structured_documents:_VisualEditor,_Citations_and_Wikidata,_oh_my!):
```
{{<<{{cite|id=“32412”}}|<<<
First person plural pronouns in Isthmus-Mecayapan Nahuat:
:''nejamēn'' ({{IPA|[nehameːn]}}) "We, but not you" (= me & them)
:''tejamēn'' ({{IPA|[tehameːn]}}) "We along with you" (= me & you & them)
{{>>cite}}>>>}}
```
Note that it was easy to surround the entire text covered by the citation into the `{{cite}}` template, since I didn't need to worry about the fact that the text included the special character `=`.
**Additional arguments** (optional extension)**Visual Editor use**
From experience with [mustache templates](https://mustache.github.io/) which have a [similar construct](https://mustache.github.io/mustache.5.html#Sections) (well, actually with the [spacebars](https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md) equivalentWhen escaping template parameters, Visual Editor would wrap the parameter with `<<<...>>>` if the input wikitext contained `|` or `=` (instead of encoding `|` as `{{!}}`, etc). If the parameter also contained `>>>`, it would generate `N<<<...>>>N`, which shares a concern that template contents be well-balanced), it seems that a large number of use cases can be satisfied with only one (or two) "heredoc arguments"picking some `N` such that `>>>N` doesn't appear in the input. That would ensure clean diffs when the only change was wrapping existing wikitext into a template.
But let's say we want to allow more generality. We could support:
```
{{<<Foo|namedArg=bar|anotherNamedArg=bat}}
This first block goes in argument "1".We might also need to eventually add a flag to the data maintained by `Extension:TemplateData` to indicate that a given parameter should always be escaped with `<<<`, if that becomes the editors' preference for certain parameters.
**More general use**
{{|}}In the initial implementation, `<<<` will be recognized as a quote character only for template arguments; that is, only immediately after `=` or `|` inside double braces. We could eventually allow `<<<` as a general mechanism, for example:
Now this goes in argument "2".```
{{|}}* a <<<
Now this goes in argument "3". It's a little more natural if there are only one or two arguments,multi
but we could keep going if we wanted.line
{{>>Foo}}>>> list item
```
The `{{|}}` syntax here introduces another "gotcha" construct to beware of in the content of the argument; an alternative might be the batwing `{{>><<}}` which should be even less likely to appear "accidentally" in argument text.
Additional proposals for this syntax welcome, I'm just trying to avoid too many crazy new constructs.
**Keeping things terse**
We might allow `{{>>}}` as a shortcut to end the block argument, instead of requiring the author to repeat the name of the template. Some folks will like the brevity, others may prefer the more explicit error messages provided when you spell out the name of the template you intend to closeWe'll treat that as a separate task iff it proves interesting.
**Strict start-of-line constraints**
For ease of parsing (and reading) we can enforce the constraint that the `{{<<...}}` and `{{>>...}}` tags must be alone on their line, and that the newline following the `{{<<...}}` and `{{>>...}}` tags is not copied into the output.
We could enforce start-of-line context on the result to avoid the T14974/T2529 hacks and make behavior consistent. There might be other restrictions that would prove useful. (More thought welcome here.)
**Migrating template use**
We might allow configuring details of the parameter name(s) used for the block argument(s) via `TemplateData`, to more easily use the new syntax with existing templates. This means that every template expansion has to fetch the TemplateData, however, which would probably require new caching.
Mailing list discussion: https://lists.wikimedia.org/pipermail/wikitech-l/2015-October/083448.html
//Note: task description has been edited per parsing team meeting notes [[https://phabricator.wikimedia.org/T114432#1726161|below]]; the original syntax proposal was {{>Foo}}...{{<Foo}}//
**Alternative proposal**
// Note: task description further edited to adopt @Alsee'ss syntax proposal [below](https://phabricator.wikimedia.org/T114432#3096863) is also compelling:
```
{{<<Table|class="shiny"|<<<
| Hello || wiki = world
>>>}}
{{Section|<<<
==heading==
>>>}}
```
Note that you may still have to escape literal `<<<` if it appears in your argument;, `<nowiki>` works fine for that case (since `<<<` is not valid wikitext markup which needs to be preserved,with a few tweaks. like `|` and `=` are).
```
{{echo|<<<<nowiki>>>></nowiki>>>>}}
```