Feature Proposal:

Add the Set+/Unset+/Default+ URL param syntax defined by SetVariablePlugin to the core.

The plugin itself is too dangerous to add to core (the GET and SET macros conflict with other mechanisms and are IMHO confusing).

Motivation

Required by NatEditPlugin for the settings page, and is a really useful feature.

Description and Documentation

From CommandAndCGIScripts, documentation of the save script:

Local+name create/set a local META:PREFERENCE called name
Set+name create/set a normal topic META:PREFERENCE called name
Unset+name remove a META:PREFERENCE call name
Default+name gives a default for name. If name is set to this value, then the preference will be removed. ALERT! Requires a corresponding Set+name or Local+name to work.

Examples

%<nop>SCRIPTURL{save}%/%<nop>WEB%/%<nop>TOPIC%?Set+NAME=Gandhi;Unset+ROLE=1

%<nop>SCRIPTURL{save}%/%<nop>WEB%/%<nop>TOPIC%?Set+NAME=Gandhi;Default+NAME=Gandhi - will remove NAME (including if it already exists)

Implementation

See attached patch, which is a complete implementation including documentation and unit tests.

-- Contributors: CrawfordCurrie - 07 Apr 2012

Discussion

can you update the above (and docco) detailing what happens to non-META prefs when using this save?

It'll be nice to be able to remove the 'set' portion of PreferencesPlugin using this - so yay.

-- SvenDowideit - 07 Apr 2012

In SynchroniseInlineAndMetaPrefs, I wanted to make it so inline and META prefs weren't just equal citizens, but actually two different ways of serialising the same topic element. That way we can manipulate prefs reliably via the TOM or with QuerySearch syntax.
  • If there's an inline Set statement, it should be rewritten.
  • If there's no inline Set statement, you get a META:PREF.
  • If there's both, they both get updated.
  • If they're inconsistent, META:PREF wins (as it always has).
  • setEmbeddedStoreForm should populate virtual META:PREFERENCEs for inline prefs, cf. META:CREATEINFO in trunk now Tasks.Item10678

However, I wrote a huge proposal and I think my core aims were lost in the sea of detail.

I think people agree in principle, but IIRC Crawford wanted to see a spec wrt inline vs META prefs differing capabilities to store multi-line values, also what should happen when there are multiple conflicting Set statements on the page.

-- PaulHarvey - 08 Apr 2012 - 01:45

The above proposal doesn't suffice to implement the settings page in NatEditPlugin or any other settings page where there's a need to know the default value of a preference setting.

Basically, a default preference setting is the value it would have taken when the setting wasn't set in the current (topic) scope. A default value is normally set in the WebPreferences, SitePreferences or the user's profile page. SetVariablePlugin implemented means to retrieve that value. Actually, there is no way to retrieve the exact default value as it is lost when computing the current preference hash. It only can be approximated by fetching the value as it would have been being currently at the WebPreferences or SitePreferences. This is feasible using the Foswiki::Func::pushTopicContext()= API. Note that this is not exactly the same as the default value in of a preference variable. There could very well be a local preference setting at WebPreferences that could interfere with the default value under consideration.

That's why there is %GETVAR{...scope="..."}% in SetVariablePlugin. This indeed overlaps with any other mechanism to retrieve a preference value part of the core. However, to my knowledge, none of the core mechanisms in existence really is able to fetch a preference setting from a different context, i.e. leverages Foswiki::Func::pushTopicContext() to wiki applications.

Only then will we be able to actually implement the user interface and make effective use of things like %SCRIPTURL{save}%/%WEB%/%TOPIC%?Set+NAME=Gandhi;Default+NAME=Gandhi

Here's an example to illustrate how things go together:

*Content Language*:
<input type='hidden' name='Default+CONTENT_LANGUAGE' value='%GETVAR{"CONTENT_LANGUAGE" scope="web" default="detect"}%' />
<select name="Local+CONTENT_LANGUAGE" class="foswikiSelect">
  <option value='en'>English</option>
  <option value='de'>German</option>
  <option value='fr'>French</option>
</select>

This should allow to set the content language of a topic when it diverges from the one set in the WebPreferences. Given the users selects "English" and this is the default set in WebPreferences or SitePreferences, then no topic preferences must be set when saving the topic. If the user selects something else, a proper Local setting will be set. When there is no default set in web or site preferences, the default value is "detect".

-- MichaelDaum - 10 Apr 2012

A default value for a preference is the value of that preference for the current user in the web context i.e. as if viewing the WebPreferences page. The existing EXPAND macro already does that e.g. %EXPAND{"BALLOON" scope="WebPreferences"}% will give the "default" value of BALLOON. Or am I missing something?

I agree about the resolution of the inline .vs. meta preferences; this needs to be fixed. The code I used for the patch comes (almost) verbatim from SetVariablePlugin, which does not handle this.

I have read SynchroniseInlineAndMetaPrefs, and agree with the principle, with one exception; when a pref is copied into META:PREFERENCE on a save, I favour changing the store version so that the unserialiser knows whether it needs to parse prefs out of topic content or not. This would avoid the topic text having to be scanned at all. Note for VC handlers; a topic modified on disc would also need to be re-parsed when it is updated.

Michael, my issues with SetVariablePlugin are several:
  1. A topic which =%INCLUDE='s another topic containing a SETVAR in the included topic, but the change is saved in the saved topic.
  2. SETVAR, UNSETVAR have complex and confusing mechanisms for filtering on the value of form fields which, while duplicate one of the functions of %IF.
  3. SETVAR and UNSETVAR are "implicit POST params" - you are effectively embedding actors directly into topic text. This makes it exceptionally difficult to filter these operations. As such SETVAR and UNSETVAR duplicate the function of the "real" post params. The documentation does not say which wins between a proper POST param or an implicit SETVAR post param.
  4. GETVAR duplicates the function of EXPAND; if the functionality is required, it should be merged with EXPAND.

-- CrawfordCurrie - 12 Apr 2012

That's an accurate description of SETVAR and UNSETVAR. Even more, the actors can be embedded into view templates. The main application of this is to automatically sync ACLs based on the content of a formfield, for instance when the user switches a formfield between published and unpublished will the ACLs reflect this automatically.

I didn't know about EXPAND's scope param. Cool. Wasn't there when I first wrote SetVariablePlugin. I will update NatEditPlugin's Permissions tab to make use of it.

Note that EXPAND scope webprefs will happily return a *Local BALLOON = foo and not the Set variation, which makes the difference between default and "value as seen from webprefs".

-- MichaelDaum - 12 Apr 2012

Been experimenting with EXPAND and BALLOON{default}.

Now what we need is a mechanism to distinguish the default value from the current value in the case the current value is not set. More precisely: what is the current value while not considering any defaults?

A %GETVAR{"ALLOWTOPICCHANGE" scope="topic" default="undefined"}% will return undefined even though ALLOWTOPICCHANGE is set in the WebPreferences.

A %ALLOWTOPICCHANGE{default="undefined"}% will return AdminGroup or whatever ACLs are assigned to WebPreferences. These values should not interfere with the ACLs of the current topic.

-- MichaelDaum - 12 Apr 2012

Issues beyond the implementation of *Set etc are beyond the scope of this feature request. As written, it is accepted by the 14-day rule.

-- CrawfordCurrie - 25 Apr 2012
I Attachment Action Size Date Who Comment
patch.difdif patch.dif manage 9 K 07 Apr 2012 - 09:48 CrawfordCurrie Apply at the root of a checkout (above =core= and =UnitTestContrib= )
Topic revision: r11 - 05 Jul 2015, 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