First pass at export button

New export button appears as a page control toolbar button, a tiddler
toolbar button, and a button in the advanced search filter tab.

Initially supports exporting as static HTML, CSV, JSON or `.tid` file.

Still to do:

* Made the exporter descriptions translatable
* Hide the export button by default
* User docs
* Cleaning up the existing templates (eg,
`$:/core/templates/alltiddlers.template.html` should work by
transcluding `$:/core/templates/exporters/Static`)
* Docs for the new macros `exportButton`, `csvtiddlers` and
`jsontiddlers`

Issues:

* OS X Numbers refuses to open CSV files that have been generated in
Chrome, because it thinks they’ve been downloaded from the Internet.
Firefox works OK
* The export button won’t work within the tiddler info panel, or from
the *more* popup (this is because we don’t support nested popups)
This commit is contained in:
Jermolene 2014-11-10 20:59:15 +00:00
parent 147f404a41
commit 6fc5c70ace
14 changed files with 249 additions and 3 deletions

View File

@ -24,6 +24,12 @@ Encryption/ClearPassword/Caption: clear password
Encryption/ClearPassword/Hint: Clear the password and save this wiki without encryption
Encryption/SetPassword/Caption: set password
Encryption/SetPassword/Hint: Set a password for saving this wiki with encryption
ExportPage/Caption: export all
ExportPage/Hint: Export all tiddlers
ExportTiddler/Caption: export tiddler
ExportTiddler/Hint: Export tiddler
ExportTiddlers/Caption: export tiddlers
ExportTiddlers/Hint: Export tiddlers
FullScreen/Caption: full-screen
FullScreen/Hint: Enter or leave full-screen mode
Import/Caption: import

View File

@ -0,0 +1,75 @@
/*\
title: $:/core/modules/macros/csvtiddlers.js
type: application/javascript
module-type: macro
Macro to output tiddlers matching a filter to CSV
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Information about this macro
*/
exports.name = "csvtiddlers";
exports.params = [
{name: "filter"},
{name: "format"},
];
/*
Run the macro
*/
exports.run = function(filter,format) {
var self = this,
tiddlers = this.wiki.filterTiddlers(filter),
tiddler,
fields = [],
t,f;
// Collect all the fields
for(t=0;t<tiddlers.length; t++) {
tiddler = this.wiki.getTiddler(tiddlers[t]);
for(f in tiddler.fields) {
if(fields.indexOf(f) === -1) {
fields.push(f);
}
}
}
// Sort the fields and bring the standard ones to the front
fields.sort();
"title text modified modifier created creator".split(" ").reverse().forEach(function(value,index) {
var p = fields.indexOf(value);
if(p !== -1) {
fields.splice(p,1);
fields.unshift(value)
}
});
// Output the column headings
var output = [], row = [];
fields.forEach(function(value) {
row.push(quoteAndEscape(value))
});
output.push(row.join(","));
// Output each tiddler
for(var t=0;t<tiddlers.length; t++) {
row = [];
tiddler = this.wiki.getTiddler(tiddlers[t]);
for(f=0; f<fields.length; f++) {
row.push(quoteAndEscape(tiddler ? tiddler.getFieldString(fields[f]) || "" : ""));
}
output.push(row.join(","));
}
return output.join("\n");
};
function quoteAndEscape(value) {
return "\"" + value.replace(/"/mg,"\"\"") + "\"";
}
})();

View File

@ -0,0 +1,44 @@
/*\
title: $:/core/modules/macros/jsontiddlers.js
type: application/javascript
module-type: macro
Macro to output tiddlers matching a filter to JSON
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Information about this macro
*/
exports.name = "jsontiddlers";
exports.params = [
{name: "filter"}
];
/*
Run the macro
*/
exports.run = function(filter) {
var tiddlers = this.wiki.filterTiddlers(filter),
data = [];
for(var t=0;t<tiddlers.length; t++) {
var tiddler = this.wiki.getTiddler(tiddlers[t]);
if(tiddler) {
var fields = new Object();
for(var field in tiddler.fields) {
fields[field] = tiddler.getFieldString(field);
}
data.push(fields);
}
}
return JSON.stringify(data,null,$tw.config.preferences.jsonSpaces);
};
})();

View File

@ -0,0 +1,9 @@
title: $:/core/templates/exporters/CsvFile
tags: $:/tags/Exporter
description: CSV tiddlers file
filename: tiddlers.csv
\define renderContent()
<$text text=<<csvtiddlers filter:"""$(exportFilter)$""" format:"quoted-comma-sep">>/>
\end
<<renderContent>>

View File

@ -0,0 +1,9 @@
title: $:/core/templates/exporters/JsonFile
tags: $:/tags/Exporter
description: JSON tiddlers file
filename: tiddlers.json
\define renderContent()
<$text text=<<jsontiddlers filter:"""$(exportFilter)$""">>/>
\end
<<renderContent>>

View File

@ -0,0 +1,33 @@
title: $:/core/templates/exporters/Static
tags: $:/tags/Exporter
description: Tiddlers as static HTML
filename: static.tiddlers.html
\define tv-wikilink-template() #$uri_encoded$
\define tv-config-toolbar-icons() no
\define tv-config-toolbar-text() no
\define tv-config-toolbar-class() tc-btn-invisible
\rules only filteredtranscludeinline transcludeinline
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="generator" content="TiddlyWiki" />
<meta name="tiddlywiki-version" content="{{$:/core/templates/version}}" />
<meta name="format-detection" content="telephone=no">
<link id="faviconLink" rel="shortcut icon" href="favicon.ico">
<title>{{$:/core/wiki/title}}</title>
<div id="styleArea">
{{$:/boot/boot.css||$:/core/templates/css-tiddler}}
</div>
<style type="text/css">
{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}
</style>
</head>
<body class="tc-body">
{{$:/StaticBanner||$:/core/templates/html-tiddler}}
<section class="tc-story-river">
{{$:/core/templates/exporters/Static/Content||$:/core/templates/html-tiddler}}
</section>
</body>
</html>

View File

@ -0,0 +1,8 @@
title: $:/core/templates/exporters/Static/Content
\define renderContent()
{{{ $(exportFilter)$ ||$:/core/templates/static-tiddler}}}
\end
<$importvariables filter="[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]">
<<renderContent>>
</$importvariables>

View File

@ -0,0 +1,9 @@
title: $:/core/templates/exporters/TidFile
tags: $:/tags/Exporter
description: Plain text .tid tiddler file
filename: tiddler.tid
\define renderContent()
{{{ $(exportFilter)$ +[limit[1]] ||$:/core/templates/tid-tiddler}}}
\end
<$importvariables filter="[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]"><<renderContent>></$importvariables>

View File

@ -7,7 +7,19 @@ caption: {{$:/language/Search/Filter/Caption}}
<<lingo Filter/Hint>>
<div class="tc-search tc-advanced-search"><$edit-text tiddler="$:/temp/advancedsearch" type="search" tag="input"/> <$button popup=<<qualify "$:/state/filterDropdown">> class="tc-btn-invisible">{{$:/core/images/down-arrow}}</$button> <$reveal state="$:/temp/advancedsearch" type="nomatch" text=""> <$link to="" class="tc-btn-invisible">{{$:/core/images/close-button}}</$link></$reveal></div>
<div class="tc-search tc-advanced-search">
<$edit-text tiddler="$:/temp/advancedsearch" type="search" tag="input"/>
<$button popup=<<qualify "$:/state/filterDropdown">> class="tc-btn-invisible">
{{$:/core/images/down-arrow}}
</$button>
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
<$button class="tc-btn-invisible">
<$action-setfield $tiddler="$:/temp/advancedsearch" $field="text" $value=""/>
{{$:/core/images/close-button}}
</$button>
<$macrocall $name="exportButton" exportFilter={{$:/temp/advancedsearch}} lingoBase="$:/language/Buttons/ExportTiddlers/"/>
</$reveal>
</div>
<div class="tc-block-dropdown-wrapper">
<$reveal state=<<qualify "$:/state/filterDropdown">> type="nomatch" text="" default="">

View File

@ -0,0 +1,6 @@
title: $:/core/ui/Buttons/export-page
tags: $:/tags/PageControls
caption: {{$:/core/images/export-button}} {{$:/language/Buttons/ExportPage/Caption}}
description: {{$:/language/Buttons/ExportPage/Hint}}
<$macrocall $name="exportButton" exportFilter="[!is[system]sort[title]]" lingoBase="$:/language/Buttons/ExportPage/"/>

View File

@ -0,0 +1,9 @@
title: $:/core/ui/Buttons/export-tiddler
tags: $:/tags/ViewToolbar
caption: {{$:/core/images/export-button}} {{$:/language/Buttons/ExportTiddler/Caption}}
description: {{$:/language/Buttons/ExportTiddler/Hint}}
\define makeExportFilter()
[[$(currentTiddler)$]]
\end
<$macrocall $name="exportButton" exportFilter=<<makeExportFilter>> lingoBase="$:/language/Buttons/ExportTiddler/"/>

View File

@ -0,0 +1,26 @@
title: $:/core/macros/export
tags: $:/tags/Macro
\define exportButton(exportFilter:"[!is[system]sort[title]]",lingoBase)
<$button popup=<<qualify "$:/state/popup/export">> tooltip={{$lingoBase$Hint}} aria-label={{$lingoBase$Caption}} class=<<tv-config-toolbar-class>> selectedClass="tc-selected">
<$list filter="[<tv-config-toolbar-icons>prefix[yes]]">
{{$:/core/images/export-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>prefix[yes]]">
<span class="tc-btn-text"><$text text={{$lingoBase$Caption}}/></span>
</$list>
</$button>
<$reveal state=<<qualify "$:/state/popup/export">> type="popup" position="below" animate="yes">
<div class="tc-drop-down">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Exporter]]">
<$set name="filename" value={{!!filename}}>
<$button class="tc-btn-invisible">
<$action-sendmessage $message="tm-download-file" $param=<<currentTiddler>> exportFilter="""$exportFilter$""" filename=<<filename>>/>
<$action-deletetiddler $tiddler=<<qualify "$:/state/popup/export">>/>
<$transclude field="description"/>
</$button>
</$set>
</$list>
</div>
</$reveal>
\end

View File

@ -1,2 +1,2 @@
title: $:/tags/PageControls
list: [[$:/core/ui/Buttons/home]] [[$:/core/ui/Buttons/close-all]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/new-tiddler]] [[$:/core/ui/Buttons/new-journal]] [[$:/core/ui/Buttons/import]] [[$:/core/ui/Buttons/control-panel]] [[$:/core/ui/Buttons/advanced-search]] [[$:/core/ui/Buttons/tag-manager]] [[$:/core/ui/Buttons/language]] [[$:/core/ui/Buttons/theme]] [[$:/core/ui/Buttons/storyview]] [[$:/core/ui/Buttons/encryption]] [[$:/core/ui/Buttons/full-screen]] [[$:/core/ui/Buttons/save-wiki]] [[$:/core/ui/Buttons/refresh]] [[$:/core/ui/Buttons/more-page-actions]]
list: [[$:/core/ui/Buttons/home]] [[$:/core/ui/Buttons/close-all]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/new-tiddler]] [[$:/core/ui/Buttons/new-journal]] [[$:/core/ui/Buttons/import]] [[$:/core/ui/Buttons/control-panel]] [[$:/core/ui/Buttons/advanced-search]] [[$:/core/ui/Buttons/tag-manager]] [[$:/core/ui/Buttons/language]] [[$:/core/ui/Buttons/theme]] [[$:/core/ui/Buttons/storyview]] [[$:/core/ui/Buttons/encryption]] [[$:/core/ui/Buttons/full-screen]] [[$:/core/ui/Buttons/export-page]] [[$:/core/ui/Buttons/save-wiki]] [[$:/core/ui/Buttons/refresh]] [[$:/core/ui/Buttons/more-page-actions]]

View File

@ -1,2 +1,2 @@
title: $:/tags/ViewToolbar
list: [[$:/core/ui/Buttons/more-tiddler-actions]] [[$:/core/ui/Buttons/info]] [[$:/core/ui/Buttons/new-here]] [[$:/core/ui/Buttons/new-journal-here]] [[$:/core/ui/Buttons/clone]] [[$:/core/ui/Buttons/edit]] [[$:/core/ui/Buttons/permalink]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/close-others]] [[$:/core/ui/Buttons/close]]
list: [[$:/core/ui/Buttons/more-tiddler-actions]] [[$:/core/ui/Buttons/info]] [[$:/core/ui/Buttons/new-here]] [[$:/core/ui/Buttons/new-journal-here]] [[$:/core/ui/Buttons/clone]] [[$:/core/ui/Buttons/export-tiddler]] [[$:/core/ui/Buttons/edit]] [[$:/core/ui/Buttons/permalink]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/close-others]] [[$:/core/ui/Buttons/close]]