Feature Proposal: Enable an old feature that has limited exposure.

Motivation

Found this feature accidentally while looking at the code. Seems a shame to let it linger when all the work was done. Seems to have been in the code since T* days.

Description and Documentation

There is an alternative "friendly" implementation of the macro attribute parser that supports much more flexible macro arguments, including
  • single quotes
  • comma separated attributes
  • unquoted spaceless values
  • spaces around the =
It's documented in Foswiki::Func::registerTagHandler()
  • $syntax can be 'classic' (the default) or 'context-free'. (context-free may be removed in future)
'classic' syntax is appropriate where you want the variable to support classic syntax i. e. to accept the standard %MYVAR{ "unnamed" param1="value1" param2="value2" }% syntax, as well as an unquoted default parameter, such as %<nop<MYVAR{unquoted parameter}%.

If your variable will only use named parameters, you can use 'context-free' syntax, which supports a more relaxed syntax. For example,

%MYVAR{param1=value1, value 2, param3="value 3", param4='value 5"}%

Examples

Impact

Not sure yet. I did change the default to "friendly" and the unit tests continued to pass.

%WHATDOESITAFFECT%
edit

Implementation

Add a configuration option {FeatureAccess}{ContextFreeMacros} Default to true, to enable the more generous parser by default.

If existing macros have issues, they can be set to "classic" format in their registration processing.

-- Contributors: GeorgeClark - 27 Feb 2017

Discussion

I think the biggest part of this is documenting it.

-- Main.CrawfordCurrie - 28 Feb 2017 - 10:05

The biggest issue / downside with this is that many of our core macros are documented as using quoted parameters, but work fine without the quotes.
  • %INCLUDE{Sometopic}%
  • %ICONURLPATH{some-icon}%
  • ... etc.

I see a couple of possible ways to address this:
  1. Set all these old macros .. probably most of them, to "classical" format.
  2. Change all use of these older macros to quote the default parameter.
    • This means that sites upgrading to Foswiki 2.2. will most likely have to run with the legacy operation enabled.
  3. Look at fixing the friendly parser to be more willing to accept an unquoted default parameter. Maybe allowing the "first" string found to be considered the default rather than treated as a boolean.

I'm not sure where to go. I'll commit what I have into the Item14398 branch.

-- GeorgeClark - 14 May 2017

Reviewing our docs, the "default" parameter is very clearly documented as needing to be quoted. All our examples consistently "quote the default parameter". However our internal use of the macros, especially ICON / ICONURL / ICONURLPATH is predominantly unquoted, except for the examples in the Var* documentation topics.

-- GeorgeClark - 14 May 2017

In thinking about the friendly parser, what if the parser always assigned the first string as the _DEFAULT instead of treating it as a boolean. Actually the comment in the code suggests:
# simple name with no value (boolean, or _DEFAULT)
However, as implemented, the simple name with no value is always treated as a boolean. So maybe this is actually a bug. The following change would cause code to actually match the comment:
diff --git a/core/lib/Foswiki/Attrs.pm b/core/lib/Foswiki/Attrs.pm
index 67bb7a5..8f5e34c 100644
--- a/core/lib/Foswiki/Attrs.pm
+++ b/core/lib/Foswiki/Attrs.pm
@@ -247,7 +247,14 @@ sub _friendly {
 
         # simple name with no value (boolean, or _DEFAULT)
         elsif ( $string =~ s/^[\s,]*([a-z][a-z0-9_]*)\b//is ) {
-            $this->{$1} = 1;
+            if ( defined( $this->{_DEFAULT} ) ) {
+                $this->{$1} = 1;
+            }
+            else {
+                $key = '_DEFAULT';
+                $this->{_DEFAULT} = $1;
+            }
+
         }
 
         # otherwise the whole string - sans padding - is the default

With this change, the IF tests - which is the only macro in core currently using the friendly parser, still pass.

-- GeorgeClark - 13 Jul 2017

Not quite enough. The simple name match should be space/comma delimited. The \b will split strings at special characters, like :. In addition to a simple name match, it needs similar match for a space delimited string. ie doc:Foswiki::Macros should work as a default parameter unquoted. With the above code "doc" gets matched as a boolean as : matches the \b boundary.

-- GeorgeClark - 13 Jul 2017

Deferring this to 3.0. This is too significant a change for a minor release.

-- GeorgeClark - 30 Jan 2018
 
Topic revision: r11 - 30 Jan 2018, GeorgeClark
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy