From a350a76a007e64bb2c0ffd97cae5c4fbd14b4c07 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Mon, 15 Nov 2021 21:06:47 +0000 Subject: [PATCH] Add "cascade" filter run prefix and use it to control view templates (#6168) * Initial Commit * Set currentTiddler and ..currentTiddler for filter evaulation * Precompile the filters for performance * Add explicit test for empty result when no filter passes * Use the cascade filter run prefix to choose the view template body template * Use the cascade mechanism to choose between the edit and view templates * Simplify cascade filter Thanks @saqimtiaz * Add control panel UI for inspecting the template cascades * Refactor import listing and plugin listing as alternate body templates As suggested by @pmario * Refer to $:/core/ui/{View|Edit}Template via their associated config tiddlers * Fix typo in previous commit * Add demo of custom story tiddler template * Tweak control panel wording * Standardise "Story Tiddler Template" nomenclature * Add a cascade for the editor template body * Add a cascade for the view template title * Avoid unwanted whitespace * Add a cascade for dynamically choosing tiddler icons --- core/language/en-GB/ControlPanel.multids | 13 +++++ core/modules/filterrunprefixes/cascade.js | 51 ++++++++++++++++++ core/ui/ControlPanel/Cascades.tid | 9 ++++ .../Cascades/EditTemplateBody.tid | 9 ++++ .../ui/ControlPanel/Cascades/StoryTiddler.tid | 9 ++++ core/ui/ControlPanel/Cascades/TiddlerIcon.tid | 9 ++++ .../Cascades/ViewTemplateBody.tid | 9 ++++ .../Cascades/ViewTemplateTitle.tid | 9 ++++ core/ui/EditTemplate/body.tid | 54 +------------------ core/ui/EditTemplate/body/canonical-uri.tid | 13 +++++ core/ui/EditTemplate/body/default.tid | 38 +++++++++++++ core/ui/ListTaggedCascade.tid | 14 +++++ core/ui/PageTemplate/story.tid | 2 +- core/ui/StoryTiddlerTemplate.tid | 3 ++ core/ui/TagPickerTagTemplate.tid | 2 +- core/ui/TagTemplate.tid | 2 +- core/ui/TiddlerIcon.tid | 15 ++++++ core/ui/ViewTemplate/body.tid | 10 +--- core/ui/ViewTemplate/body/blank.tid | 3 ++ core/ui/ViewTemplate/body/code.tid | 3 ++ core/ui/ViewTemplate/body/default.tid | 7 +++ core/ui/ViewTemplate/{ => body}/import.tid | 3 +- core/ui/ViewTemplate/body/plugin.tid | 10 ++++ core/ui/ViewTemplate/plugin.tid | 15 ------ core/ui/ViewTemplate/title.tid | 26 ++------- core/ui/ViewTemplate/title/default.tid | 6 +++ core/ui/ViewTemplate/title/system.tid | 6 +++ .../config/EditTemplateBodyFilters.multids | 5 ++ .../StoryTiddlerTemplateFilters.multids | 5 ++ core/wiki/config/TiddlerIconFilters.multids | 5 ++ .../config/ViewTemplateBodyFilters.multids | 8 +++ .../config/ViewTemplateTitleFilters.multids | 5 ++ core/wiki/macros/tag.tid | 6 +-- core/wiki/tags/EditTemplateBodyFilter.tid | 2 + core/wiki/tags/StoryTiddlerTemplateFilter.tid | 2 + core/wiki/tags/TiddlerIconFilter.tid | 3 ++ core/wiki/tags/ViewTemplateBodyFilter.tid | 3 ++ core/wiki/tags/ViewTemplateTitleFilter.tid | 3 ++ .../tiddlers/tests/test-prefixes-filter.js | 32 +++++++++++ ...ist with Custom Story Tiddler Template.tid | 9 ++++ .../Styles.tid | 31 +++++++++++ .../Template.tid | 22 ++++++++ .../TiddlerTemplateFilter.tid | 5 ++ .../CustomTiddlerIconCascadeDemo.tid | 5 ++ 44 files changed, 394 insertions(+), 107 deletions(-) create mode 100644 core/modules/filterrunprefixes/cascade.js create mode 100644 core/ui/ControlPanel/Cascades.tid create mode 100644 core/ui/ControlPanel/Cascades/EditTemplateBody.tid create mode 100644 core/ui/ControlPanel/Cascades/StoryTiddler.tid create mode 100644 core/ui/ControlPanel/Cascades/TiddlerIcon.tid create mode 100644 core/ui/ControlPanel/Cascades/ViewTemplateBody.tid create mode 100644 core/ui/ControlPanel/Cascades/ViewTemplateTitle.tid create mode 100644 core/ui/EditTemplate/body/canonical-uri.tid create mode 100644 core/ui/EditTemplate/body/default.tid create mode 100644 core/ui/ListTaggedCascade.tid create mode 100644 core/ui/StoryTiddlerTemplate.tid create mode 100644 core/ui/TiddlerIcon.tid create mode 100644 core/ui/ViewTemplate/body/blank.tid create mode 100644 core/ui/ViewTemplate/body/code.tid create mode 100644 core/ui/ViewTemplate/body/default.tid rename core/ui/ViewTemplate/{ => body}/import.tid (93%) create mode 100644 core/ui/ViewTemplate/body/plugin.tid delete mode 100644 core/ui/ViewTemplate/plugin.tid create mode 100644 core/ui/ViewTemplate/title/default.tid create mode 100644 core/ui/ViewTemplate/title/system.tid create mode 100644 core/wiki/config/EditTemplateBodyFilters.multids create mode 100644 core/wiki/config/StoryTiddlerTemplateFilters.multids create mode 100644 core/wiki/config/TiddlerIconFilters.multids create mode 100644 core/wiki/config/ViewTemplateBodyFilters.multids create mode 100644 core/wiki/config/ViewTemplateTitleFilters.multids create mode 100644 core/wiki/tags/EditTemplateBodyFilter.tid create mode 100644 core/wiki/tags/StoryTiddlerTemplateFilter.tid create mode 100644 core/wiki/tags/TiddlerIconFilter.tid create mode 100644 core/wiki/tags/ViewTemplateBodyFilter.tid create mode 100644 core/wiki/tags/ViewTemplateTitleFilter.tid create mode 100644 editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Demo Tiddler List with Custom Story Tiddler Template.tid create mode 100644 editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Styles.tid create mode 100644 editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Template.tid create mode 100644 editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/TiddlerTemplateFilter.tid create mode 100644 editions/tw5.com/tiddlers/demonstrations/CustomTiddlerIconCascadeDemo/CustomTiddlerIconCascadeDemo.tid diff --git a/core/language/en-GB/ControlPanel.multids b/core/language/en-GB/ControlPanel.multids index 5c105edbb..f813cc356 100644 --- a/core/language/en-GB/ControlPanel.multids +++ b/core/language/en-GB/ControlPanel.multids @@ -27,10 +27,15 @@ Basics/Tiddlers/Prompt: Number of tiddlers Basics/Title/Prompt: Title of this ~TiddlyWiki Basics/Username/Prompt: Username for signing edits Basics/Version/Prompt: ~TiddlyWiki version +Cascades/Caption: Cascades +Cascades/Hint: These global rules are used to dynamically choose certain templates. The result of the cascade is the result of the first filter in the sequence that returns a result +Cascades/TagPrompt: Filters tagged <$macrocall $name="tag" tag=<>/> EditorTypes/Caption: Editor Types EditorTypes/Editor/Caption: Editor EditorTypes/Hint: These tiddlers determine which editor is used to edit specific tiddler types. EditorTypes/Type/Caption: Type +EditTemplateBody/Caption: Edit Template Body +EditTemplateBody/Hint: This rule cascade is used by the default edit template to dynamically choose the template for editing the body of a tiddler. Info/Caption: Info Info/Hint: Information about this TiddlyWiki KeyboardShortcuts/Add/Prompt: Type shortcut here @@ -191,6 +196,8 @@ Settings/TitleLinks/Yes/Description: Display tiddler titles as links Settings/MissingLinks/Caption: Wiki Links Settings/MissingLinks/Hint: Choose whether to link to tiddlers that do not exist yet Settings/MissingLinks/Description: Enable links to missing tiddlers +StoryTiddler/Caption: Story Tiddler +StoryTiddler/Hint: This rule cascade is used to dynamically choose the template for displaying a tiddler in the story river. StoryView/Caption: Story View StoryView/Prompt: Current view: Stylesheets/Caption: Stylesheets @@ -201,6 +208,8 @@ Theme/Caption: Theme Theme/Prompt: Current theme: TiddlerFields/Caption: Tiddler Fields TiddlerFields/Hint: This is the full set of TiddlerFields in use in this wiki (including system tiddlers but excluding shadow tiddlers). +TiddlerIcon/Caption: Tiddler Icon +TiddlerIcon/Hint: This rules cascade is used to dynamically choose the icon for a tiddler. Toolbars/Caption: Toolbars Toolbars/EditToolbar/Caption: Edit Toolbar Toolbars/EditToolbar/Hint: Choose which buttons are displayed for tiddlers in edit mode. Drag and drop to change the ordering @@ -212,3 +221,7 @@ Toolbars/EditorToolbar/Hint: Choose which buttons are displayed in the editor to Toolbars/ViewToolbar/Caption: View Toolbar Toolbars/ViewToolbar/Hint: Choose which buttons are displayed for tiddlers in view mode. Drag and drop to change the ordering Tools/Download/Full/Caption: Download full wiki +ViewTemplateBody/Caption: View Template Body +ViewTemplateBody/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the body of a tiddler. +ViewTemplateTitle/Caption: View Template Title +ViewTemplateTitle/Hint: This rule cascade is used by the default view template to dynamically choose the template for displaying the title of a tiddler. \ No newline at end of file diff --git a/core/modules/filterrunprefixes/cascade.js b/core/modules/filterrunprefixes/cascade.js new file mode 100644 index 000000000..b42119d7b --- /dev/null +++ b/core/modules/filterrunprefixes/cascade.js @@ -0,0 +1,51 @@ +/*\ +title: $:/core/modules/filterrunprefixes/cascade.js +type: application/javascript +module-type: filterrunprefix +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +/* +Export our filter prefix function +*/ +exports.cascade = function(operationSubFunction,options) { + return function(results,source,widget) { + if(results.length !== 0) { + var filterList = operationSubFunction(source,widget), + filterFnList = []; + var inputResults = results.toArray(); + results.clear(); + $tw.utils.each(inputResults,function(title) { + var result = ""; // If no filter matches, we return an empty string + $tw.utils.each(filterList,function(filter,index) { + if(!filterFnList[index]) { + filterFnList[index] = options.wiki.compileFilter(filter); + } + var output = filterFnList[index](options.wiki.makeTiddlerIterator([title]),{ + getVariable: function(name) { + switch(name) { + case "currentTiddler": + return "" + title; + case "..currentTiddler": + return widget.getVariable("currentTiddler"); + default: + return widget.getVariable(name); + } + } + }); + if(output.length !== 0) { + result = output[0]; + return false; + } + }); + results.push(result); + }); + } + } +}; + +})(); \ No newline at end of file diff --git a/core/ui/ControlPanel/Cascades.tid b/core/ui/ControlPanel/Cascades.tid new file mode 100644 index 000000000..bbd5a3750 --- /dev/null +++ b/core/ui/ControlPanel/Cascades.tid @@ -0,0 +1,9 @@ +title: $:/core/ui/ControlPanel/Cascades +tags: $:/tags/ControlPanel/Advanced +caption: {{$:/language/ControlPanel/Cascades/Caption}} + +{{$:/language/ControlPanel/Cascades/Hint}} + +
+<$macrocall $name="tabs" tabsList="[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Cascades]!has[draft.of]]" default="$:/core/ui/ControlPanel/StoryTiddler"/> +
diff --git a/core/ui/ControlPanel/Cascades/EditTemplateBody.tid b/core/ui/ControlPanel/Cascades/EditTemplateBody.tid new file mode 100644 index 000000000..8558cfebc --- /dev/null +++ b/core/ui/ControlPanel/Cascades/EditTemplateBody.tid @@ -0,0 +1,9 @@ +title: $:/core/ui/ControlPanel/EditTemplateBody +tags: $:/tags/ControlPanel/Cascade +caption: {{$:/language/ControlPanel/EditTemplateBody/Caption}} + +\define lingo-base() $:/language/ControlPanel/EditTemplateBody/ + +<> + +{{$:/tags/EditTemplateBodyFilter||$:/snippets/ListTaggedCascade}} diff --git a/core/ui/ControlPanel/Cascades/StoryTiddler.tid b/core/ui/ControlPanel/Cascades/StoryTiddler.tid new file mode 100644 index 000000000..3fcf0819b --- /dev/null +++ b/core/ui/ControlPanel/Cascades/StoryTiddler.tid @@ -0,0 +1,9 @@ +title: $:/core/ui/ControlPanel/StoryTiddler +tags: $:/tags/ControlPanel/Cascades +caption: {{$:/language/ControlPanel/StoryTiddler/Caption}} + +\define lingo-base() $:/language/ControlPanel/StoryTiddler/ + +<> + +{{$:/tags/StoryTiddlerTemplateFilter||$:/snippets/ListTaggedCascade}} diff --git a/core/ui/ControlPanel/Cascades/TiddlerIcon.tid b/core/ui/ControlPanel/Cascades/TiddlerIcon.tid new file mode 100644 index 000000000..82e369b08 --- /dev/null +++ b/core/ui/ControlPanel/Cascades/TiddlerIcon.tid @@ -0,0 +1,9 @@ +title: $:/core/ui/ControlPanel/TiddlerIcon +tags: $:/tags/ControlPanel/Cascades +caption: {{$:/language/ControlPanel/TiddlerIcon/Caption}} + +\define lingo-base() $:/language/ControlPanel/TiddlerIcon/ + +<> + +{{$:/tags/TiddlerIconFilter||$:/snippets/ListTaggedCascade}} diff --git a/core/ui/ControlPanel/Cascades/ViewTemplateBody.tid b/core/ui/ControlPanel/Cascades/ViewTemplateBody.tid new file mode 100644 index 000000000..1347f6826 --- /dev/null +++ b/core/ui/ControlPanel/Cascades/ViewTemplateBody.tid @@ -0,0 +1,9 @@ +title: $:/core/ui/ControlPanel/ViewTemplateBody +tags: $:/tags/ControlPanel/Cascades +caption: {{$:/language/ControlPanel/ViewTemplateBody/Caption}} + +\define lingo-base() $:/language/ControlPanel/ViewTemplateBody/ + +<> + +{{$:/tags/ViewTemplateBodyFilter||$:/snippets/ListTaggedCascade}} diff --git a/core/ui/ControlPanel/Cascades/ViewTemplateTitle.tid b/core/ui/ControlPanel/Cascades/ViewTemplateTitle.tid new file mode 100644 index 000000000..7a0d203b6 --- /dev/null +++ b/core/ui/ControlPanel/Cascades/ViewTemplateTitle.tid @@ -0,0 +1,9 @@ +title: $:/core/ui/ControlPanel/ViewTemplateTitle +tags: $:/tags/ControlPanel/Cascades +caption: {{$:/language/ControlPanel/ViewTemplateTitle/Caption}} + +\define lingo-base() $:/language/ControlPanel/ViewTemplateTitle/ + +<> + +{{$:/tags/ViewTemplateTitleFilter||$:/snippets/ListTaggedCascade}} diff --git a/core/ui/EditTemplate/body.tid b/core/ui/EditTemplate/body.tid index 34b4f0af8..8dd691d44 100644 --- a/core/ui/EditTemplate/body.tid +++ b/core/ui/EditTemplate/body.tid @@ -1,56 +1,4 @@ title: $:/core/ui/EditTemplate/body tags: $:/tags/EditTemplate -\define lingo-base() $:/language/EditTemplate/Body/ -\define config-visibility-title() -$:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$ -\end - -\define importFileActions() -<$action-popup $state=<> $coords="(0,0,0,0)" $floating="yes"/> -\end - -<$list filter="[all[current]has[_canonical_uri]]"> - -
- -<> - -<$text text={{!!_canonical_uri}}/> - -<$edit-text field="_canonical_uri" class="tc-edit-fields" tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"> - -
- - - -<$set name="edit-preview-state" value={{{ [{$:/config/ShowEditPreview/PerTiddler}!match[yes]then[$:/state/showeditpreview]] :else[] }}}> -<$list filter="[all[current]!has[_canonical_uri]]"> -<$vars importTitle=<> importState=<> > -<$dropzone importTitle=<> autoOpenOnImport="no" contentTypesFilter={{$:/config/Editor/ImportContentTypesFilter}} class="tc-dropzone-editor" enable={{{ [{$:/config/DragAndDrop/Enable}match[no]] :else[subfilter{$:/config/Editor/EnableImportFilter}then[yes]else[no]] }}} filesOnly="yes" actions=<> ><$reveal stateTitle=<> type="match" text="yes"> -
- -<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/> - -
- -<$transclude tiddler={{$:/state/editpreviewtype}} mode="inline"> - -<$transclude tiddler="$:/core/ui/EditTemplate/body/preview/output" mode="inline"/> - - - -
- -
- - -<$reveal stateTitle=<> type="nomatch" text="yes"> - -<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/> - - - - - - +<$transclude tiddler={{{ [] :cascade[all[shadows+tiddlers]tag[$:/tags/EditTemplateBodyFilter]get[text]] :and[!is[blank]else[$:/core/ui/EditTemplate/body/default]] }}} /> diff --git a/core/ui/EditTemplate/body/canonical-uri.tid b/core/ui/EditTemplate/body/canonical-uri.tid new file mode 100644 index 000000000..c39470469 --- /dev/null +++ b/core/ui/EditTemplate/body/canonical-uri.tid @@ -0,0 +1,13 @@ +title: $:/core/ui/EditTemplate/body/canonical-uri + +\define lingo-base() $:/language/EditTemplate/Body/ + +
+ +<> + +<$text text={{!!_canonical_uri}}/> + +<$edit-text field="_canonical_uri" class="tc-edit-fields" tabindex={{$:/config/EditTabIndex}} cancelPopups="yes"> + +
diff --git a/core/ui/EditTemplate/body/default.tid b/core/ui/EditTemplate/body/default.tid new file mode 100644 index 000000000..c9dadc6c4 --- /dev/null +++ b/core/ui/EditTemplate/body/default.tid @@ -0,0 +1,38 @@ +title: $:/core/ui/EditTemplate/body/default + +\define config-visibility-title() +$:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$ +\end + +\define importFileActions() +<$action-popup $state=<> $coords="(0,0,0,0)" $floating="yes"/> +\end + +<$set name="edit-preview-state" value={{{ [{$:/config/ShowEditPreview/PerTiddler}!match[yes]then[$:/state/showeditpreview]] :else[] }}}> +<$vars importTitle=<> importState=<> > +<$dropzone importTitle=<> autoOpenOnImport="no" contentTypesFilter={{$:/config/Editor/ImportContentTypesFilter}} class="tc-dropzone-editor" enable={{{ [{$:/config/DragAndDrop/Enable}match[no]] :else[subfilter{$:/config/Editor/EnableImportFilter}then[yes]else[no]] }}} filesOnly="yes" actions=<> ><$reveal stateTitle=<> type="match" text="yes"> +
+ +<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/> + +
+ +<$transclude tiddler={{$:/state/editpreviewtype}} mode="inline"> + +<$transclude tiddler="$:/core/ui/EditTemplate/body/preview/output" mode="inline"/> + + + +
+ +
+ + +<$reveal stateTitle=<> type="nomatch" text="yes"> + +<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/> + + + + + diff --git a/core/ui/ListTaggedCascade.tid b/core/ui/ListTaggedCascade.tid new file mode 100644 index 000000000..3342838a2 --- /dev/null +++ b/core/ui/ListTaggedCascade.tid @@ -0,0 +1,14 @@ +title: $:/snippets/ListTaggedCascade + +{{||$:/language/ControlPanel/Cascades/TagPrompt}} + +
    +<$list filter="[all[shadows+tiddlers]tag]"> +
  1. +
    +<$link><$text text=<>/> +
    +<$codeblock code={{!!text}}/> +
  2. + +
diff --git a/core/ui/PageTemplate/story.tid b/core/ui/PageTemplate/story.tid index 1fa0e6db3..66b90778a 100644 --- a/core/ui/PageTemplate/story.tid +++ b/core/ui/PageTemplate/story.tid @@ -14,7 +14,7 @@ tags: $:/tags/PageTemplate -<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" template={{$:/config/ui/ViewTemplate}} editTemplate={{$:/config/ui/EditTemplate}} storyview={{$:/view}} emptyMessage={{$:/config/EmptyStoryMessage}}/> +<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" template="$:/core/ui/StoryTiddlerTemplate" storyview={{$:/view}} emptyMessage={{$:/config/EmptyStoryMessage}}/>
diff --git a/core/ui/StoryTiddlerTemplate.tid b/core/ui/StoryTiddlerTemplate.tid new file mode 100644 index 000000000..9daef8864 --- /dev/null +++ b/core/ui/StoryTiddlerTemplate.tid @@ -0,0 +1,3 @@ +title: $:/core/ui/StoryTiddlerTemplate + +<$transclude tiddler={{{ [] :cascade[all[shadows+tiddlers]tag[$:/tags/StoryTiddlerTemplateFilter]get[text]] :and[!is[blank]else{$:/config/ui/ViewTemplate}] }}} /> diff --git a/core/ui/TagPickerTagTemplate.tid b/core/ui/TagPickerTagTemplate.tid index 0588a0698..9e967bc7b 100644 --- a/core/ui/TagPickerTagTemplate.tid +++ b/core/ui/TagPickerTagTemplate.tid @@ -16,7 +16,7 @@ title: $:/core/ui/TagPickerTagTemplate <$set name="backgroundColor" value={{!!color}}> <$wikify name="foregroundColor" text="""<$macrocall $name="contrastcolour" target={{!!color}} fallbackTarget=<> colourA=<> colourB=<>/>"""> >> -<$transclude tiddler={{!!icon}}/><$view field="title" format="text"/> +{{||$:/core/ui/TiddlerIcon}}<$view field="title" format="text"/> diff --git a/core/ui/TagTemplate.tid b/core/ui/TagTemplate.tid index 3856854f5..fb9ce16ba 100644 --- a/core/ui/TagTemplate.tid +++ b/core/ui/TagTemplate.tid @@ -3,7 +3,7 @@ title: $:/core/ui/TagTemplate \whitespace trim >> <$set name="transclusion" value=<>> -<$macrocall $name="tag-pill-body" tag=<> icon={{!!icon}} colour={{!!color}} palette={{$:/palette}} element-tag="""$button""" element-attributes="""popup=<> dragFilter='[all[current]tagging[]]' tag='span'"""/> +<$macrocall $name="tag-pill-body" tag=<> colour={{!!color}} palette={{$:/palette}} element-tag="""$button""" element-attributes="""popup=<> dragFilter='[all[current]tagging[]]' tag='span'"""/> <$reveal state=<> type="popup" position="below" animate="yes" class="tc-drop-down"> <$set name="tv-show-missing-links" value="yes"> <$transclude tiddler="$:/core/ui/ListItemTemplate"/> diff --git a/core/ui/TiddlerIcon.tid b/core/ui/TiddlerIcon.tid new file mode 100644 index 000000000..bf4f79999 --- /dev/null +++ b/core/ui/TiddlerIcon.tid @@ -0,0 +1,15 @@ +title: $:/core/ui/TiddlerIcon + +\whitespace trim +\define title-styles() +fill:$(foregroundColor)$; +\end +<$let tiddlerIcon={{{ [] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]get[text]] }}}> +<$list filter="[!is[blank]]" variable="ignore"> +<$let foregroundColor={{!!color}}> +> style=<>> +<$transclude tiddler=<>/> + + + + diff --git a/core/ui/ViewTemplate/body.tid b/core/ui/ViewTemplate/body.tid index a09e4753f..ef4de3272 100644 --- a/core/ui/ViewTemplate/body.tid +++ b/core/ui/ViewTemplate/body.tid @@ -3,14 +3,6 @@ tags: $:/tags/ViewTemplate <$reveal tag="div" class="tc-tiddler-body" type="nomatch" stateTitle=<> text="hide" retain="yes" animate="yes"> -<$list filter="[all[current]!has[plugin-type]!field:hide-body[yes]]"> - -<$transclude> - -<$transclude tiddler="$:/language/MissingTiddler/Hint"/> - - - - +<$transclude tiddler={{{ [] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateBodyFilter]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/body/default]] }}} /> diff --git a/core/ui/ViewTemplate/body/blank.tid b/core/ui/ViewTemplate/body/blank.tid new file mode 100644 index 000000000..1c72f5983 --- /dev/null +++ b/core/ui/ViewTemplate/body/blank.tid @@ -0,0 +1,3 @@ +title: $:/core/ui/ViewTemplate/body/blank + + diff --git a/core/ui/ViewTemplate/body/code.tid b/core/ui/ViewTemplate/body/code.tid new file mode 100644 index 000000000..8c0494b19 --- /dev/null +++ b/core/ui/ViewTemplate/body/code.tid @@ -0,0 +1,3 @@ +title: $:/core/ui/ViewTemplate/body/code + +<$codeblock code={{{ [get[text]] }}} language={{{ [get[type]else[text/vnd.tiddlywiki]] }}}/> diff --git a/core/ui/ViewTemplate/body/default.tid b/core/ui/ViewTemplate/body/default.tid new file mode 100644 index 000000000..083684879 --- /dev/null +++ b/core/ui/ViewTemplate/body/default.tid @@ -0,0 +1,7 @@ +title: $:/core/ui/ViewTemplate/body/default + +<$transclude> + +<$transclude tiddler="$:/language/MissingTiddler/Hint"/> + + diff --git a/core/ui/ViewTemplate/import.tid b/core/ui/ViewTemplate/body/import.tid similarity index 93% rename from core/ui/ViewTemplate/import.tid rename to core/ui/ViewTemplate/body/import.tid index 33e13fcae..93018f627 100644 --- a/core/ui/ViewTemplate/import.tid +++ b/core/ui/ViewTemplate/body/import.tid @@ -1,5 +1,4 @@ -title: $:/core/ui/ViewTemplate/import -tags: $:/tags/ViewTemplate +title: $:/core/ui/ViewTemplate/body/import \define lingo-base() $:/language/Import/ diff --git a/core/ui/ViewTemplate/body/plugin.tid b/core/ui/ViewTemplate/body/plugin.tid new file mode 100644 index 000000000..decbfaf1a --- /dev/null +++ b/core/ui/ViewTemplate/body/plugin.tid @@ -0,0 +1,10 @@ +title: $:/core/ui/ViewTemplate/body/plugin + +
+<$let plugin-type={{!!plugin-type}} + default-popup-state="yes" + qualified-state=<> +> +{{||$:/core/ui/Components/plugin-info}} + +
\ No newline at end of file diff --git a/core/ui/ViewTemplate/plugin.tid b/core/ui/ViewTemplate/plugin.tid deleted file mode 100644 index 564b209b3..000000000 --- a/core/ui/ViewTemplate/plugin.tid +++ /dev/null @@ -1,15 +0,0 @@ -title: $:/core/ui/ViewTemplate/plugin -tags: $:/tags/ViewTemplate - -<$reveal tag="div" class="tc-tiddler-plugin-info" type="nomatch" stateTitle=<> text="hide" retain="yes" animate="yes"> - -<$list filter="[all[current]has[plugin-type]] -[all[current]field:plugin-type[import]]"> -<$set name="plugin-type" value={{!!plugin-type}}> -<$set name="default-popup-state" value="yes"> -<$set name="qualified-state" value=<>> -{{||$:/core/ui/Components/plugin-info}} - - - - - \ No newline at end of file diff --git a/core/ui/ViewTemplate/title.tid b/core/ui/ViewTemplate/title.tid index 6c518baa7..019948a4d 100644 --- a/core/ui/ViewTemplate/title.tid +++ b/core/ui/ViewTemplate/title.tid @@ -2,9 +2,6 @@ title: $:/core/ui/ViewTemplate/title tags: $:/tags/ViewTemplate \whitespace trim -\define title-styles() -fill:$(foregroundColor)$; -\end
@@ -12,25 +9,10 @@ fill:$(foregroundColor)$; <$set name="tv-wikilinks" value={{$:/config/Tiddlers/TitleLinks}}> <$link> -<$set name="foregroundColor" value={{!!color}}> -<$list filter="[all[current]has[icon]]~[[$:/config/DefaultTiddlerIcon]has[text]]"> ->> -<$transclude tiddler={{!!icon}}> -<$transclude tiddler={{$:/config/DefaultTiddlerIcon}}/> - - - - -<$list filter="[all[current]removeprefix[$:/]]"> -

-$:/<$text text=<>/> -

- -<$list filter="[all[current]!prefix[$:/]]"> -

-<$view field="title"/> -

- +<$let iconSpanClass="tc-tiddler-title-icon"> +{{||$:/core/ui/TiddlerIcon}} + +<$transclude tiddler={{{ [] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateTitleFilter]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/title/default]] }}} />
diff --git a/core/ui/ViewTemplate/title/default.tid b/core/ui/ViewTemplate/title/default.tid new file mode 100644 index 000000000..2791e98a0 --- /dev/null +++ b/core/ui/ViewTemplate/title/default.tid @@ -0,0 +1,6 @@ +title: $:/core/ui/ViewTemplate/title/default + +\whitespace trim +

+<$view field="title"/> +

diff --git a/core/ui/ViewTemplate/title/system.tid b/core/ui/ViewTemplate/title/system.tid new file mode 100644 index 000000000..987aca120 --- /dev/null +++ b/core/ui/ViewTemplate/title/system.tid @@ -0,0 +1,6 @@ +title: $:/core/ui/ViewTemplate/title/system + +\whitespace trim +

+$:/<$text text={{{ [removeprefix[$:/]] }}}/> +

\ No newline at end of file diff --git a/core/wiki/config/EditTemplateBodyFilters.multids b/core/wiki/config/EditTemplateBodyFilters.multids new file mode 100644 index 000000000..6623c2843 --- /dev/null +++ b/core/wiki/config/EditTemplateBodyFilters.multids @@ -0,0 +1,5 @@ +title: $:/config/EditTemplateBodyFilters/ +tags: $:/tags/EditTemplateBodyFilter + +canonical-uri: [has[_canonical_uri]then[$:/core/ui/EditTemplate/body/canonical-uri]] +default: [[$:/core/ui/EditTemplate/body/default]] diff --git a/core/wiki/config/StoryTiddlerTemplateFilters.multids b/core/wiki/config/StoryTiddlerTemplateFilters.multids new file mode 100644 index 000000000..30f7e2b80 --- /dev/null +++ b/core/wiki/config/StoryTiddlerTemplateFilters.multids @@ -0,0 +1,5 @@ +title: $:/config/StoryTiddlerTemplateFilters/ +tags: $:/tags/StoryTiddlerTemplateFilter + +draft: [is[draft]then{$:/config/ui/EditTemplate}] +default: [{$:/config/ui/ViewTemplate}] diff --git a/core/wiki/config/TiddlerIconFilters.multids b/core/wiki/config/TiddlerIconFilters.multids new file mode 100644 index 000000000..1ed156c2e --- /dev/null +++ b/core/wiki/config/TiddlerIconFilters.multids @@ -0,0 +1,5 @@ +title: $:/config/TiddlerIconFilters/ +tags: $:/tags/TiddlerIconFilter + +icon-field: [has[icon]then{!!icon}] +default: [{$:/config/DefaultTiddlerIcon}has[text]] diff --git a/core/wiki/config/ViewTemplateBodyFilters.multids b/core/wiki/config/ViewTemplateBodyFilters.multids new file mode 100644 index 000000000..3bc1fba5b --- /dev/null +++ b/core/wiki/config/ViewTemplateBodyFilters.multids @@ -0,0 +1,8 @@ +title: $:/config/ViewTemplateBodyFilters/ +tags: $:/tags/ViewTemplateBodyFilter + +system: [prefix[$:/boot/]] [prefix[$:/config/]] [prefix[$:/core/]!field:title[$:/core/readme]!field:title[$:/core/icon]] [prefix[$:/info/]] [prefix[$:/language/]] [prefix[$:/languages/]] [prefix[$:/snippets/]] [prefix[$:/state/]] [prefix[$:/status/]] [prefix[$:/info/]] [prefix[$:/temp/]] +[limit[1]then[$:/core/ui/ViewTemplate/body/code]] +import: [field:plugin-type[import]then[$:/core/ui/ViewTemplate/body/import]] +plugin: [has[plugin-type]then[$:/core/ui/ViewTemplate/body/plugin]] +hide-body: [field:hide-body[yes]then[$:/core/ui/ViewTemplate/body/blank]] +default: [[$:/core/ui/ViewTemplate/body/default]] diff --git a/core/wiki/config/ViewTemplateTitleFilters.multids b/core/wiki/config/ViewTemplateTitleFilters.multids new file mode 100644 index 000000000..938211311 --- /dev/null +++ b/core/wiki/config/ViewTemplateTitleFilters.multids @@ -0,0 +1,5 @@ +title: $:/config/ViewTemplateTitleFilters/ +tags: $:/tags/ViewTemplateTitleFilter + +system: [prefix[$:/]then[$:/core/ui/ViewTemplate/title/system]] +default: [[$:/core/ui/ViewTemplate/title/default]] diff --git a/core/wiki/macros/tag.tid b/core/wiki/macros/tag.tid index f19a0b978..a9644725e 100644 --- a/core/wiki/macros/tag.tid +++ b/core/wiki/macros/tag.tid @@ -10,18 +10,18 @@ color:$(foregroundColor)$; \define tag-pill-inner(tag,icon,colour,fallbackTarget,colourA,colourB,element-tag,element-attributes,actions) <$vars foregroundColor=<> backgroundColor="""$colour$"""> <$element-tag$ $element-attributes$ class="tc-tag-label tc-btn-invisible" style=<>> -$actions$<$transclude tiddler="""$icon$"""/><$view tiddler=<<__tag__>> field="title" format="text" /> +$actions${{||$:/core/ui/TiddlerIcon}}<$view tiddler=<<__tag__>> field="title" format="text" /> \end \define tag-pill-body(tag,icon,colour,palette,element-tag,element-attributes,actions) -<$macrocall $name="tag-pill-inner" tag=<<__tag__>> icon="""$icon$""" colour="""$colour$""" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/> +<$macrocall $name="tag-pill-inner" tag=<<__tag__>> colour="""$colour$""" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/> \end \define tag-pill(tag,element-tag:"span",element-attributes:"",actions:"") >> -<$macrocall $name="tag-pill-body" tag=<<__tag__>> icon={{{ [<__tag__>get[icon]] }}} colour={{{ [<__tag__>get[color]] }}} palette={{$:/palette}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/> +<$macrocall $name="tag-pill-body" tag=<<__tag__>> colour={{{ [<__tag__>get[color]] }}} palette={{$:/palette}} element-tag="""$element-tag$""" element-attributes="""$element-attributes$""" actions="""$actions$"""/> \end diff --git a/core/wiki/tags/EditTemplateBodyFilter.tid b/core/wiki/tags/EditTemplateBodyFilter.tid new file mode 100644 index 000000000..6ed816b11 --- /dev/null +++ b/core/wiki/tags/EditTemplateBodyFilter.tid @@ -0,0 +1,2 @@ +title: $:/tags/EditTemplateBodyFilter +list: $:/config/EditTemplateBodyFilters/canonical-uri $:/config/EditTemplateBodyFilters/default \ No newline at end of file diff --git a/core/wiki/tags/StoryTiddlerTemplateFilter.tid b/core/wiki/tags/StoryTiddlerTemplateFilter.tid new file mode 100644 index 000000000..2d8f0c14c --- /dev/null +++ b/core/wiki/tags/StoryTiddlerTemplateFilter.tid @@ -0,0 +1,2 @@ +title: $:/tags/StoryTiddlerTemplateFilter +list: $:/config/StoryTiddlerTemplateFilters/draft $:/config/StoryTiddlerTemplateFilters/default diff --git a/core/wiki/tags/TiddlerIconFilter.tid b/core/wiki/tags/TiddlerIconFilter.tid new file mode 100644 index 000000000..e55f9ab52 --- /dev/null +++ b/core/wiki/tags/TiddlerIconFilter.tid @@ -0,0 +1,3 @@ +title: $:/tags/TiddlerIconFilter +list: $:/config/TiddlerIconFilters/icon-field $:/config/TiddlerIconFilters/default + diff --git a/core/wiki/tags/ViewTemplateBodyFilter.tid b/core/wiki/tags/ViewTemplateBodyFilter.tid new file mode 100644 index 000000000..5fa531119 --- /dev/null +++ b/core/wiki/tags/ViewTemplateBodyFilter.tid @@ -0,0 +1,3 @@ +title: $:/tags/ViewTemplateBodyFilter +list: $:/config/ViewTemplateBodyFilters/system $:/config/ViewTemplateBodyFilters/import $:/config/ViewTemplateBodyFilters/plugin $:/config/ViewTemplateBodyFilters/hide-body $:/config/ViewTemplateBodyFilters/default + diff --git a/core/wiki/tags/ViewTemplateTitleFilter.tid b/core/wiki/tags/ViewTemplateTitleFilter.tid new file mode 100644 index 000000000..24f3fb580 --- /dev/null +++ b/core/wiki/tags/ViewTemplateTitleFilter.tid @@ -0,0 +1,3 @@ +title: $:/tags/ViewTemplateTitleFilter +list: $:/config/ViewTemplateTitleFilters/system $:/config/ViewTemplateTitleFilters/default + diff --git a/editions/test/tiddlers/tests/test-prefixes-filter.js b/editions/test/tiddlers/tests/test-prefixes-filter.js index e6c418d84..1008f9279 100644 --- a/editions/test/tiddlers/tests/test-prefixes-filter.js +++ b/editions/test/tiddlers/tests/test-prefixes-filter.js @@ -288,6 +288,38 @@ describe("'reduce' and 'intersection' filter prefix tests", function() { tags: ["cakes","with tea"], text: "Does anyone eat pound cake?" }); + wiki.addTiddler({ + title: "$:/filter1", + text: "[tag[cakes]then[It is customary]]", + tags: "$:/tags/Filter $:/tags/SecondFilter" + }); + wiki.addTiddler({ + title: "$:/filter2", + text: "[tag[shopping]then[It is not customary]]", + tags: "$:/tags/Filter $:/tags/SecondFilter" + }); + wiki.addTiddler({ + title: "$:/filter3", + text: "[[Just a default]]", + tags: "$:/tags/Filter" + }); + wiki.addTiddler({ + title: "$:/tags/Filter", + list: "$:/filter1 $:/filter2 $:/filter3" + }); + wiki.addTiddler({ + title: "$:/tags/SecondFilter", + list: "$:/filter1 $:/filter2" + }); + + it("should handle the :cascade filter prefix", function() { + expect(wiki.filterTiddlers("[[Rice Pudding]] :cascade[all[shadows+tiddlers]tag[$:/tags/Filter]get[text]]").join(",")).toBe("It is not customary"); + expect(wiki.filterTiddlers("[[chocolate cake]] :cascade[all[shadows+tiddlers]tag[$:/tags/Filter]get[text]]").join(",")).toBe("It is customary"); + expect(wiki.filterTiddlers("[[Sparkling water]] :cascade[all[shadows+tiddlers]tag[$:/tags/Filter]get[text]]").join(",")).toBe("Just a default"); + expect(wiki.filterTiddlers("[[Rice Pudding]] :cascade[all[shadows+tiddlers]tag[$:/tags/SecondFilter]get[text]]").join(",")).toBe("It is not customary"); + expect(wiki.filterTiddlers("[[chocolate cake]] :cascade[all[shadows+tiddlers]tag[$:/tags/SecondFilter]get[text]]").join(",")).toBe("It is customary"); + expect(wiki.filterTiddlers("[[Sparkling water]] :cascade[all[shadows+tiddlers]tag[$:/tags/SecondFilter]get[text]]").join(",")).toBe(""); + }); it("should handle the :reduce filter prefix", function() { expect(wiki.filterTiddlers("[tag[shopping]] :reduce[get[quantity]add]").join(",")).toBe("22"); diff --git a/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Demo Tiddler List with Custom Story Tiddler Template.tid b/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Demo Tiddler List with Custom Story Tiddler Template.tid new file mode 100644 index 000000000..226bf1710 --- /dev/null +++ b/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Demo Tiddler List with Custom Story Tiddler Template.tid @@ -0,0 +1,9 @@ +title: Demo Tiddler List with Custom Story Tiddler Template +tags: $:/tags/TiddlerList +filter: HelloThere Community GettingStarted Features Reference Plugins Learning + +This is a demo tiddler with a custom story tiddler template. See [[Story Tiddler Templates]] for details. + +Click to close this tiddler: {{||$:/core/ui/Buttons/close}} + +Click to edit this tiddler: {{||$:/core/ui/Buttons/edit}} diff --git a/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Styles.tid b/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Styles.tid new file mode 100644 index 000000000..c0b812f8f --- /dev/null +++ b/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Styles.tid @@ -0,0 +1,31 @@ +title: $:/_tw5.com/CustomStoryTiddlerTemplateDemo/Styles +tags: $:/tags/Stylesheet + +.tc-custom-tiddler-template { + border: 3px solid <>; + border-radius: 1em; + margin-bottom: 1em; +} + +.tc-custom-tiddler-template-inner { + background: <>; + padding: 1em; +} + +.tc-custom-tiddler-template-list { + position: relative; + height: 33vh; +} + +.tc-custom-tiddler-template-list .tc-custom-tiddler-template-list-item { + position: absolute; + width: 100%; + transform-origin: 50% 0; + top: 50px; + left: 0; + <> +} + +.tc-custom-tiddler-template-list .tc-custom-tiddler-template-list-item .tc-tiddler-frame { + margin: 0; +} \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Template.tid b/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Template.tid new file mode 100644 index 000000000..1753163e7 --- /dev/null +++ b/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/Template.tid @@ -0,0 +1,22 @@ +title: $:/_tw5.com/CustomStoryTiddlerTemplateDemo/Template + +\define list-item-styles() +transform: translate($(left)$%,$(top)$%) scale(0.3) rotate($(angle)$deg); +\end + +
+
+ <$transclude mode="block"/> +
+
+ <$let numItems={{{ [subfilter{!!filter}count[]] }}} angleIncrement={{{ [[45]divide] }}} posIncrement={{{ [[90]divide] }}}> + <$list filter={{!!filter}} counter="counter"> + <$let angle={{{ [subtract[1]multiplysubtract[22.5]] }}} left={{{ [subtract[1]multiplysubtract[45]] }}} top={{{ 0 }}}> +
>> + {{||$:/core/ui/ViewTemplate}} +
+ + + +
+
diff --git a/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/TiddlerTemplateFilter.tid b/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/TiddlerTemplateFilter.tid new file mode 100644 index 000000000..dddb3d62a --- /dev/null +++ b/editions/tw5.com/tiddlers/demonstrations/CustomStoryTiddlerTemplateDemo.tid/TiddlerTemplateFilter.tid @@ -0,0 +1,5 @@ +title: $:/_tw5.com/CustomStoryTiddlerTemplateDemo/Filter +tags: $:/tags/StoryTiddlerTemplateFilter +list-before: $:/config/StoryTiddlerTemplateFilters/default + +[tag[$:/tags/TiddlerList]then[$:/_tw5.com/CustomStoryTiddlerTemplateDemo/Template]] diff --git a/editions/tw5.com/tiddlers/demonstrations/CustomTiddlerIconCascadeDemo/CustomTiddlerIconCascadeDemo.tid b/editions/tw5.com/tiddlers/demonstrations/CustomTiddlerIconCascadeDemo/CustomTiddlerIconCascadeDemo.tid new file mode 100644 index 000000000..64158f5bb --- /dev/null +++ b/editions/tw5.com/tiddlers/demonstrations/CustomTiddlerIconCascadeDemo/CustomTiddlerIconCascadeDemo.tid @@ -0,0 +1,5 @@ +title: $:/_tw5.com/CustomTiddlerIconCascadeDemo +tags: $:/tags/TiddlerIconFilter + +[tag[TableOfContents]then[$:/core/images/globe]] +[tag[Working with TiddlyWiki]then[$:/core/images/help]]