1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-09-28 15:08:46 +00:00

First commit

This commit is contained in:
jeremy@jermolene.com 2021-03-22 09:34:32 +00:00
parent 9c31ff1fb1
commit 42e10d030a
20 changed files with 700 additions and 10 deletions

View File

@ -757,7 +757,12 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
tiddler = $tw.wiki.getTiddler(name),
_exports = {},
sandbox = {
module: {exports: _exports},
module: {
exports: _exports,
setStringHandler: function(handler) {
moduleInfo.stringHandler = handler;
}
},
//moduleInfo: moduleInfo,
exports: _exports,
console: console,
@ -821,7 +826,7 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
moduleInfo.definition(moduleInfo,moduleInfo.exports,sandbox.require);
} else if(typeof moduleInfo.definition === "string") { // String
moduleInfo.exports = _exports;
$tw.utils.evalSandboxed(moduleInfo.definition,sandbox,tiddler.fields.title);
$tw.utils.evalSandboxed(moduleInfo.definition,sandbox,name);
if(sandbox.module.exports) {
moduleInfo.exports = sandbox.module.exports; //more codemirror workaround
}
@ -918,6 +923,20 @@ $tw.modules.createClassesFromModules = function(moduleType,subType,baseClass) {
return classes;
};
/*
Return a specified module string for a module, null if the module or string is missing
*/
$tw.modules.getModuleString = function(moduleName,stringName,language) {
if(moduleName in $tw.modules.titles) {
$tw.modules.execute(moduleName);
var stringHandler = $tw.modules.titles[moduleName].stringHandler;
if(stringHandler) {
return stringHandler(stringName,language);
}
}
return null;
};
/////////////////////////// Barebones tiddler object
/*

7
core/images/publish.tid Normal file
View File

@ -0,0 +1,7 @@
title: $:/core/images/publish
tags: $:/tags/Image
<svg width="22pt" height="22pt" class="tc-image-publish tc-image-button" viewBox="0 0 128 128"><g fill-rule="evenodd">
<path d="M64.0434107,46.2358498 C65.8048912,45.8955184 67.6195684,46.7809274 68.4102078,48.4458716 L68.4937877,48.6340507 L98.8972485,122.034498 C99.7426494,124.075476 98.7734424,126.415349 96.7324641,127.26075 C94.7552664,128.079732 92.4975633,127.195747 91.5897922,125.284145 L91.5062123,125.095966 L88.403,117.605598 L79.5048497,126.50485 C78.775871,127.233828 77.8355254,127.622617 76.8810886,127.671216 L76.6764226,127.676423 C75.6527333,127.676423 74.6290441,127.285898 73.8479955,126.50485 L63.999,116.656598 L54.1520045,126.50485 C53.4230259,127.233828 52.4826802,127.622617 51.5282434,127.671216 L51.3235774,127.676423 C50.2998881,127.676423 49.2761989,127.285898 48.4951503,126.50485 L39.596,117.605598 L36.4937877,125.095966 C35.6483868,127.136944 33.3085142,128.106151 31.2675359,127.26075 C29.2265576,126.415349 28.2573506,124.075476 29.1027515,122.034498 L59.5062123,48.6340507 C60.2518688,46.8338766 62.1601511,45.867488 64.0005148,46.2445933 L64.0434107,46.2358498 Z M77.679,102.976598 L69.656,110.999598 L76.676,118.018598 L84.699,109.996598 L77.679,102.976598 Z M50.326,102.983598 L43.307,110.002598 L51.323,118.018598 L58.342,110.999598 L50.326,102.983598 Z M64.006,89.3035977 L55.983,97.3265977 L63.999,105.342598 L72.022,97.3195977 L64.006,89.3035977 Z M55.035,80.3325977 L50.348,91.6475977 L58.349,83.6465977 L55.035,80.3325977 Z M72.968,80.3415977 L69.663,83.6465977 L77.642,91.6255977 L72.968,80.3415977 Z M64,58.6895977 L58.3344072,72.3699713 C58.4295481,72.4423583 58.5221874,72.5195778 58.6119911,72.6016299 L58.7445283,72.7283325 L64.006,77.9895977 L69.2684411,72.7283325 C69.3957231,72.6010505 69.5294489,72.4841397 69.6685683,72.3775999 L64,58.6895977 Z M38.5026635,2.59571369 C40.7118025,2.59571369 42.5026635,4.38657469 42.5026635,6.59571369 C42.5026635,7.7643162 42.0015346,8.8158738 41.2024517,9.54721162 L41.372583,9.372583 C35.581722,15.163444 32,23.163444 32,32 C32,40.8370609 35.5821314,48.8374703 41.3735757,54.6284097 C42.0884306,55.3520538 42.531226,56.3471171 42.531226,57.4456008 C42.531226,59.6547398 40.740365,61.4456008 38.531226,61.4456008 C37.4327422,61.4456008 36.4376789,61.0028055 35.7147885,60.2859673 L35.7048234,60.2963403 C28.472656,53.0586276 24,43.0631255 24,32.0229786 C24,21.1046577 28.3744907,11.2080539 35.4664167,3.99022262 C36.2004724,3.13678606 37.2883808,2.59571369 38.5026635,2.59571369 Z M89.3688013,2.48959773 C90.5097745,2.48959773 91.5391719,2.96731026 92.2678917,3.73363348 L92.2733617,3.72780197 C99.5183488,10.9672382 104,20.9717355 104,32.0229786 C104,42.8488024 99.6993143,52.6701472 92.7132398,59.8717162 C91.9816831,60.8152368 90.8371876,61.4223982 89.5508819,61.4223982 C87.3417429,61.4223982 85.5508819,59.6315372 85.5508819,57.4223982 C85.5508819,56.3502862 85.9726717,55.3766885 86.6593633,54.6584932 L86.627417,54.627417 C92.418278,48.836556 96,40.836556 96,32 C96,23.2702193 92.5043135,15.3568999 86.8363661,9.5834674 C85.9399594,8.85136737 85.3688013,7.73718311 85.3688013,6.48959773 C85.3688013,4.28045873 87.1596623,2.48959773 89.3688013,2.48959773 Z M50.0871028,13.6297119 C52.2962418,13.6297119 54.0871028,15.4205729 54.0871028,17.6297119 C54.0871028,18.8506134 53.5401157,19.9437593 52.6778337,20.6774573 L52.6862915,20.6862915 C49.790861,23.581722 48,27.581722 48,32 C48,36.4187838 49.791271,40.4191937 52.6872859,43.3147028 L52.6777105,43.3251493 C53.4423082,44.0537041 53.918794,45.0819221 53.918794,46.2214294 C53.918794,48.4305684 52.127933,50.2214294 49.918794,50.2214294 C48.6900999,50.2214294 47.5907975,49.6674376 46.8570439,48.7956109 L47.0304281,48.9715536 C42.6867001,44.6283295 40,38.627921 40,32 C40,25.372583 42.6862915,19.372583 47.0294373,15.0294373 L47.0395567,15.0387468 C47.7732533,14.1766 48.8663118,13.6297119 50.0871028,13.6297119 Z M77.9823819,13.700452 C79.1679628,13.700452 80.2330731,14.2162483 80.9655529,15.0356811 L80.9715536,15.0304281 C85.314117,19.3734956 88,25.373087 88,32 C88,38.4619387 85.4461804,44.3274009 81.2927766,48.6421512 L80.9933974,48.9476975 C80.2638884,49.7186971 79.2309977,50.2000547 78.08568,50.2000547 C75.876541,50.2000547 74.08568,48.4091937 74.08568,46.2000547 C74.08568,45.0665777 74.557136,44.0432152 75.314649,43.3153662 L75.3137085,43.3137085 C78.209139,40.418278 80,36.418278 80,32 C80,27.5822253 78.209547,23.5826334 75.314698,20.6872811 C74.4981782,19.9511432 73.9823819,18.8860329 73.9823819,17.700452 C73.9823819,15.491313 75.7732429,13.700452 77.9823819,13.700452 Z M64,24 C68.418278,24 72,27.581722 72,32 C72,36.418278 68.418278,40 64,40 C59.581722,40 56,36.418278 56,32 C56,27.581722 59.581722,24 64,24 Z"></path>
</g>
</svg>

View File

@ -83,6 +83,8 @@ Permaview/Caption: permaview
Permaview/Hint: Set browser address bar to a direct link to all the tiddlers in this story
Print/Caption: print page
Print/Hint: Print the current page
Publish/Caption: publish
Publish/Hint: Publish from the wiki
Refresh/Caption: refresh
Refresh/Hint: Perform a full refresh of the wiki
Save/Caption: ok

View File

@ -96,6 +96,8 @@ Plugins/Updates/Caption: Updates
Plugins/Updates/Hint: Available updates to installed plugins
Plugins/Updates/UpdateAll/Caption: Update <<update-count>> plugins
Plugins/SubPluginPrompt: With <<count>> sub-plugins available
Publishing/Caption: Publishing
Publishing/Hint: Settings used for publishing extracts from this TiddlyWiki as separate files through a "publisher" module
Saving/Caption: Saving
Saving/DownloadSaver/AutoSave/Description: Permit automatic saving for the download saver
Saving/DownloadSaver/AutoSave/Hint: Enable Autosave for Download Saver

View File

@ -40,10 +40,10 @@ Command.prototype.execute = function() {
variableList = this.params.slice(4),
tiddlers = wiki.filterTiddlers(tiddlerFilter),
variables = Object.create(null);
while(variableList.length >= 2) {
variables[variableList[0]] = variableList[1];
variableList = variableList.slice(2);
}
while(variableList.length >= 2) {
variables[variableList[0]] = variableList[1];
variableList = variableList.slice(2);
}
$tw.utils.each(tiddlers,function(title) {
var parser = wiki.parseTiddler(template || title);
var widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title})}),

View File

@ -0,0 +1,30 @@
/*\
title: $:/core/modules/filters/moduleproperty.js
type: application/javascript
module-type: filteroperator
Filter [[module-name]moduleproperty[name]] retrieve a module property
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.moduleproperty = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var value = require(title)[operator.operand || ""];
if(value !== undefined) {
results.push(value);
}
});
results.sort();
return results;
};
})();

View File

@ -17,11 +17,23 @@ Export our filter function
*/
exports.modules = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {
results.push(moduleName);
if(operator.operands.length === 1) {
// Return all the module names without filtering
source(function(tiddler,title) {
$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {
results.push(moduleName);
});
});
});
} else if(operator.operands.length >= 2) {
// Return the modules that have the module property specified in the first operand with the value in the second operand
source(function(tiddler,title) {
$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {
if(require(moduleName)[operator.operands[0]] === operator.operands[1]) {
results.push(moduleName);
}
});
});
}
results.sort();
return results;
};

View File

@ -0,0 +1,30 @@
/*\
title: $:/core/modules/filters/modulestring.js
type: application/javascript
module-type: filteroperator
Filter [[module-name]modulestring[en-gb]] retrieve a module strings in a particular language
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.modulestring = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var s = $tw.modules.getModuleString(title,operator.operands[0] || "",operator.operands[1] || "");
if(s !== null) {
results.push(s);
}
});
results.sort();
return results;
};
})();

View File

@ -0,0 +1,286 @@
/*\
title: $:/core/modules/publisherhandler.js
type: application/javascript
module-type: global
The publisher manages publishing extracts of wikis as external files
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Instantiate the publisher manager with the following options
widget: optional widget for attaching event handlers
*/
function PublisherHandler(options) {
this.widget = options.widget;
this.wiki = options.wiki;
this.reset();
if(this.widget) {
this.widget.addEventListener("tm-publish-start",this.onPublishStart.bind(this));
this.widget.addEventListener("tm-publish-route",this.onPublishRoute.bind(this));
this.widget.addEventListener("tm-publish-end",this.onPublishEnd.bind(this));
}
}
PublisherHandler.prototype.onPublishStart = function(event) {
var publisherName = event.paramObject["publisher-name"],
publisherParamsTitle = event.paramObject["publish-params-title"],
publisherParamsTiddler = publisherParamsTitle && this.wiki.getTiddler(publisherParamsTitle);
if(publisherName && publisherParamsTiddler) {
this.publisherName = publisherName;
this.publisherParamsTitle = publisherParamsTitle;
this.publisherParams = publisherParamsTiddler.fields;
this.routes = [];
}
};
PublisherHandler.prototype.onPublishEnd = function(event) {
if(this.publisherName && this.publisherParams && this.routes) {
this.publish();
}
};
PublisherHandler.prototype.onPublishRoute = function(event) {
if(this.publisherName && this.publisherParams && this.routes) {
this.routes.push(event.paramObject);
}
};
/*
Instantiate the required publisher object
*/
PublisherHandler.prototype.getPublisher = function() {
var self = this,
publisher;
$tw.modules.forEachModuleOfType("publisher",function(title,module) {
if(module.name === self.publisherName) {
publisher = module;
}
});
return publisher && publisher.create(this.publisherParams);
};
/*
Expand publish routes to separate commands
*/
PublisherHandler.prototype.expandRoutes = function(routes) {
var self = this,
commands = [];
$tw.utils.each(routes,function(route) {
var filter = route.filter || "DUMMY_RESULT"; // If no filter is provided, use a dummy filter that returns a single result
switch(route["route-type"]) {
case "save":
if(filter && route.path) {
$tw.utils.each(self.wiki.filterTiddlers(filter),function(title) {
commands.push({
"route-type": "save",
path: self.resolveParameterisedPath(route.path,title),
title: title
});
});
}
break;
case "render":
if(filter && route.path && route.template) {
$tw.utils.each(self.wiki.filterTiddlers(filter),function(title) {
commands.push({
"route-type": "render",
path: self.resolveParameterisedPath(route.path,title),
title: title,
template: route.template
});
});
}
break;
}
});
return commands;
};
/*
Apply a tiddler to a parameterised path to create a usable path
*/
PublisherHandler.prototype.resolveParameterisedPath = function(route,title) {
var self = this;
// Split the route on $$ markers
var tiddler = this.wiki.getTiddler(title),
output = [];
$tw.utils.each(route.split(/(\$[a-z_]+\$)/),function(part) {
var match = part.match(/\$([a-z]+)_([a-z]+)\$/);
if(match) {
var value;
// Get the base value
switch(match[1]) {
case "uri":
case "title":
value = title;
break;
case "type":
value = tiddler.fields.type || "text/vnd.tiddlywiki";
break;
}
// Apply the encoding function
switch(match[2]) {
case "encoded":
value = encodeURIComponent(value);
break;
case "doubleencoded":
value = encodeURIComponent(encodeURIComponent(value));
break;
case "slugify":
value = self.wiki.slugify(value);
break;
case "extension":
value = ($tw.config.contentTypeInfo[value] || {extension: "."}).extension.slice(1);
break;
}
output.push(value);
} else {
output.push(part);
}
});
return output.join("");
};
/*
Publish the routes in this.routes[]
*/
PublisherHandler.prototype.publish = function(callback) {
var self = this,
report = {overwrites: []},
commands = this.expandRoutes(this.routes),
nextCommand = 0,
publisher = this.getPublisher(),
performNextCommand = function() {
// Set progress
self.setProgress(nextCommand,commands.length);
// Check for having finished
if(nextCommand >= commands.length) {
publisher.publishEnd(function() {
self.saveReport(report);
self.reset();
self.hideProgress();
if(callback) {
$tw.utils.nextTick(callback);
}
});
} else {
// Execute this command
var fileDetails = self.prepareCommand(commands[nextCommand]);
nextCommand += 1;
publisher.publishFile(fileDetails,function() {
$tw.utils.nextTick(performNextCommand);
});
}
};
// Fail if we didn't get a publisher
if(!publisher) {
alert("Publisher " + this.publisherName + " not found");
return;
}
this.displayProgress("Publishing");
// Tell the publisher to start, and get back an array of the existing paths
publisher.publishStart(function(existingPaths) {
var paths = {};
$tw.utils.each(commands,function(command) {
if(command.path in paths) {
report.overwrites.push(command.path);
}
paths[command.path] = true;
});
// Run the commands
$tw.utils.nextTick(performNextCommand);
});
};
/*
Construct a file details object from a command object
*/
PublisherHandler.prototype.prepareCommand = function(command) {
var tiddler = this.wiki.getTiddler(command.title),
fileDetails = {
path: command.path
};
switch(command["route-type"]) {
case "save":
fileDetails.text = tiddler.fields.text || "";
fileDetails.type = tiddler.fields.type || "";
break;
case "render":
fileDetails.text = this.wiki.renderTiddler("text/plain",command.template,{variables: {currentTiddler: command.title}});
fileDetails.type = "text/html";
break;
}
return fileDetails;
};
/*
*/
PublisherHandler.prototype.reset = function() {
this.publisherName = null;
this.publisherParams = null;
this.routes = null;
};
PublisherHandler.prototype.saveReport = function(report) {
// Create the report tiddler
var reportTitle = this.wiki.generateNewTitle("$:/temp/publish-report");
$tw.wiki.addTiddler({
title: reportTitle,
text: "* " + report.overwrites.join("\n* ")
});
// Add the report tiddler title to the list field of the publisher parameters tiddler
var paramsTiddler = $tw.wiki.getTiddler(this.publisherParamsTitle),
list = (paramsTiddler.fields.list || []).slice(0);
list.unshift(reportTitle);
$tw.wiki.addTiddler(new $tw.Tiddler(paramsTiddler,{list: list}));
};
PublisherHandler.prototype.displayProgress = function(message) {
if($tw.browser) {
this.progressWrapper = document.createElement("div");
this.progressWrapper.className = "tc-progress-bar-wrapper";
this.progressText = document.createElement("div");
this.progressText.className = "tc-progress-bar-text";
this.progressText.appendChild(document.createTextNode(message));
this.progressWrapper.appendChild(this.progressText);
this.progressBar = document.createElement("div");
this.progressBar.className = "tc-progress-bar";
this.progressWrapper.appendChild(this.progressBar);
this.progressPercent = document.createElement("div");
this.progressPercent.className = "tc-progress-bar-percent";
this.progressWrapper.appendChild(this.progressPercent);
document.body.appendChild(this.progressWrapper);
}
};
PublisherHandler.prototype.hideProgress = function() {
if($tw.browser && this.progressWrapper) {
this.progressWrapper.parentNode.removeChild(this.progressWrapper);
this.progressWrapper = null;
}
};
PublisherHandler.prototype.setProgress = function(numerator,denominator) {
if($tw.browser && this.progressWrapper) {
// Remove old progress
while(this.progressPercent.hasChildNodes()) {
this.progressPercent.removeChild(this.progressPercent.firstChild);
}
// Set new text
var percent = (numerator * 100 /denominator).toFixed(2) + "%";
this.progressPercent.appendChild(document.createTextNode(percent));
// Set bar width
this.progressBar.style.width = percent;
}
};
exports.PublisherHandler = PublisherHandler;
})();

View File

@ -72,6 +72,11 @@ exports.startup = function() {
}
});
}
// Install the publisher handler
$tw.publisherHandler = new $tw.PublisherHandler({
wiki: $tw.wiki,
widget: $tw.rootWidget
});
// If we're being viewed on a data: URI then give instructions for how to save
if(document.location.protocol === "data:") {
$tw.rootWidget.dispatchEvent({

View File

@ -0,0 +1,75 @@
title: $:/core/ui/ControlPanel/Publishing
tags: $:/tags/ControlPanel
caption: {{$:/language/ControlPanel/Publishing/Caption}}
{{$:/language/ControlPanel/Publishing/Hint}}
<div class="tc-publishing-job-listing">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Publish/Jobs]]" variable="job">
<div class="tc-publishing-job">
<h2>Job: <$link to=<<job>>><$transclude tiddler=<<job>> field="caption" mode="inline"/></$link></h2>
Publisher: <$select tiddler=<<job>> field="publisher">
<$list filter="[[publisher]modules[]moduleproperty[name]]">
<option value=<<currentTiddler>>><$text text=<<currentTiddler>>/></option>
</$list>
</$select>
Base URL: <$edit-text tiddler=<<job>> size="50" field="baseurl"/>
Logs: <$view tiddler=<<job>> field="list"/>
<$set name="publisher-name" value={{{ [<job>get[publisher]] }}}>
<$set name="publisher-module" value={{{ [[publisher]modules[name],<publisher-name>] }}}>
<div class="tc-publishing-job-publisher">
<h2>Publisher: <$text text=<<publisher-name>>/></h2>
<$set name="publisher-ui" value={{{ [<publisher-module>modulestring[ui],{$:/language}] }}}>
<$tiddler tiddler=<<job>>>
<<publisher-ui>>
</$tiddler>
</$set>
</div>
<div class="tc-publishing-job-routes">
<$list filter="[all[shadows+tiddlers]tag<job>]" variable="route">
<div class="tc-publishing-route">
<h2>Route: <$link to=<<route>>><$view tiddler=<<route>> field="caption"/></$link></h2>
job-type: <$view tiddler=<<route>> field="job-type"/>
path: <$edit-text tiddler=<<route>> size="50" field="path"/>
filter: <$edit-text tiddler=<<route>> size="50" field="filter"/>
template: <$edit-text tiddler=<<route>> size="50" field="template"/>
</div>
</$list>
</div>
</$set>
</$set>
</div>
</$list>
</div>

View File

@ -0,0 +1,31 @@
title: $:/core/ui/Buttons/publish
tags: $:/tags/PageControls
caption: {{$:/core/images/publish}} {{$:/language/Buttons/Publish/Caption}}
description: {{$:/language/Buttons/Publish/Hint}}
\define publish-actions()
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Publish/Jobs]]" variable="job">
<$set name="publisher-name" value={{{ [<job>get[publisher]] }}}>
<$action-sendmessage $message="tm-publish-start" publisher-name=<<publisher-name>> publish-params-title=<<job>>/>
<$list filter="[all[shadows+tiddlers]tag<job>]" variable="route">
<$action-sendmessage $message="tm-publish-route"
caption={{{ [<route>get[caption]] }}}
route-type={{{ [<route>get[job-type]] }}}
path={{{ [<route>get[path]] }}}
filter={{{ [<route>get[filter]] }}}
template={{{ [<route>get[template]] }}}
/>
</$list>
<$action-sendmessage $message="tm-publish-end"/>
</$set>
</$list>
\end
<$button actions=<<publish-actions>> tooltip={{$:/language/Buttons/Publish/Hint}} aria-label={{$:/language/Buttons/Publish/Caption}} class=<<tv-config-toolbar-class>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{$:/core/images/publish}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Publish/Caption}}/></span>
</$list>
</$button>

View File

@ -0,0 +1,6 @@
title: $:/core/publishing-jobs/Static/Images
caption: Images
tags: $:/core/publishing-jobs/Static/Job
job-type: save
path: images/$title_slugify$.$type_extension$
filter: [is[image]]

View File

@ -0,0 +1,6 @@
title: $:/core/publishing-jobs/Static/Index
caption: Index
tags: $:/core/publishing-jobs/Static/Job
job-type: render
path: index.html
template: $:/core/save/all

View File

@ -0,0 +1,6 @@
title: $:/core/publishing-jobs/Static/Job
tags: $:/tags/Publish/Jobs
caption: Demo Static Site
publisher: jszip
jszip-output-filename: myzipfile.zip
baseurl: https://example.com

View File

@ -0,0 +1,9 @@
title: $:/core/publishing-jobs/Static/StaticHTML
caption: Static HTML
tags: $:/core/publishing-jobs/Static/Job
job-type: render
path: static/$title_slugify$.html
filter: [!is[system]!is[image]]
template: $:/core/templates/static.tiddler.html
tv-wikilink-template: $title_slugify$.html
tv-image-template: images/$title_slugify$.$type_extension$

View File

@ -0,0 +1,6 @@
title: $:/core/publishing-jobs/Static/Styles
caption: Styles
tags: $:/core/publishing-jobs/Static/Job
job-type: render
path: static/static.css
template: $:/core/templates/static.template.css

View File

@ -0,0 +1,34 @@
created: 20210315092524275
modified: 20210315093103563
tags: [[Working with TiddlyWiki]]
title: Publishing
You can publish extracts from a wiki as a collection of interconnected static files that can be hosted on the Internet independently from TiddlyWiki.
!! Terminology
TiddlyWiki has pluggable ''publisher modules'' that provide the means to publish to specific platforms:
* The JSZip publisher packs the output files in a ZIP file which is automatically downloaded by the browser
* The GitHub publisher uploads the output files to a GitHub repository suitable for GitHub Pages
A ''job'' defines a self-contained group of files to be published, and specifies the ''publisher module'' to be used along with any parameters.
Jobs consist of one or more ''routes'' which each define a related set of files that are to be treated in the same way.
Routes consist of the following information:
* A filter defining the tiddlers included in the route
* A ''parameterised path'' defining how the ''output path'' is derived from the field values of a particular tiddler
* A ''route type'' which can be set to "save" or "render":
** ''"save"'' indicates that the raw tiddler is to be saved, without any rendering
** ''"render"'' indicates that the tiddler is to be rendered through a specified ''template''
Parameterised paths are strings which may contain optional tokens of the format `fieldname_functionname`. These tokens are replaced by the value of the specified field passed through the specified encoding function. The available encoding functions are:
* ''encoded'' -- applies URI encoding to the value
* ''doubleencoded'' -- applies double URI encoding to the value
* ''slugify'' -- applies the [[slugify Operator]] to the value
* ''extension'' -- interprets the value as a content type and returns the associated file extension
For backwards compatibility, the field "uri" is accepted as a synonym for "title".

View File

@ -0,0 +1,60 @@
/*\
title: $:/plugins/tiddlywiki/jszip/jszip-publisher.js
type: application/javascript
module-type: publisher
Handles publishing to a ZIP file
\*/
(function(){
if(module.setStringHandler) {
module.setStringHandler(function(name,language) {
switch(name) {
case "ui":
return "User interface of the JSZip publisher\n\nOutput filename: <$edit-text field=jszip-output-filename/>";
}
return null;
});
}
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.name = "jszip";
var JSZip = require("$:/plugins/tiddlywiki/jszip/jszip.js");
exports.create = function(params) {
return new JSZipPublisher(params);
};
function JSZipPublisher(params) {
this.params = params;
this.zip = new JSZip();
console.log("JSZipPublisher",params);
};
JSZipPublisher.prototype.publishStart = function(callback) {
console.log("publishStart");
callback([]);
};
JSZipPublisher.prototype.publishFile = function(item,callback) {
this.zip.file(item.path,item.text);
callback();
};
JSZipPublisher.prototype.publishEnd = function(callback) {
var data = this.zip.generate({type: "base64"}),
link = document.createElement("a");
link.setAttribute("href","data:application/zip;base64," + encodeURIComponent(data));
link.setAttribute("download",this.params["jszip-output-filename"] || "site.zip");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
callback();
};
})();

View File

@ -2909,6 +2909,70 @@ select {
background: <<colour select-tag-background>>;
}
/*
Publishing UI
*/
.tc-publishing-job-listing {
margin: 0.25em;
padding: 0.25em;
border: 1px solid black;
background-color: #ddffff;
}
.tc-publishing-job {
margin: 0.25em;
padding: 0.25em;
border: 1px solid black;
background-color: #ffddff;
}
.tc-publishing-job-publisher {
margin: 0.25em;
padding: 0.25em;
border: 1px solid black;
background-color: #ffdddd;
}
.tc-publishing-job-routes {
margin: 0.25em;
padding: 0.25em;
border: 1px solid black;
background-color: #ffffdd;
}
.tc-publishing-route {
margin: 0.25em;
padding: 0.25em;
border: 1px solid black;
background-color: #ddffdd;
}
/*
Progress bar
*/
.tc-progress-bar-wrapper {
position: fixed;
width: 50%;
height: 50px;
top: 50%;
left: 50%;
margin-top: -25px;
margin-left: -25%;
background: #ffffee;
}
.tc-progress-bar-text,
.tc-progress-bar-percent {
text-align: center;
}
.tc-progress-bar {
height: 10px;
background: red;
}
/*
** Utility classes for SVG icons
*/