From f6d647894486defb7ab856da0ce1901fc0ed8750 Mon Sep 17 00:00:00 2001
From: Jeremy Ruston
Date: Tue, 23 Jan 2024 14:29:50 +0000
Subject: [PATCH] Add support for recipe descriptions
---
.../MultiWikiServer Administration.tid | 35 ++++++++++---------
.../multiwikiserver/admin-ui/Styles.tid | 19 ++++++----
.../multiwikiserver/modules/init.js | 8 ++---
.../modules/route-put-recipe-tiddler.js | 12 ++++---
.../modules/sql-tiddler-database.js | 22 ++++++++----
.../modules/sql-tiddler-store.js | 28 +++++++++------
6 files changed, 76 insertions(+), 48 deletions(-)
diff --git a/plugins/tiddlywiki/multiwikiserver/admin-ui/MultiWikiServer Administration.tid b/plugins/tiddlywiki/multiwikiserver/admin-ui/MultiWikiServer Administration.tid
index 9352ffa74..46a603907 100644
--- a/plugins/tiddlywiki/multiwikiserver/admin-ui/MultiWikiServer Administration.tid
+++ b/plugins/tiddlywiki/multiwikiserver/admin-ui/MultiWikiServer Administration.tid
@@ -50,10 +50,12 @@ title: MultiWikiServer Administration
\procedure bagPill(element-tag:"span",is-topmost:"no")
\whitespace trim
<$genesis $type=<> class={{{ mws-bag-pill [match[yes]then[mws-bag-pill-topmost]] +[join[ ]] }}}>
- <$image source=`/wiki/${ [{!!bag-name}encodeuricomponent[]] }$/bags/${ [{!!bag-name}encodeuricomponent[]] }$/tiddlers/%24%3A%2Ffavicon.ico` class="mws-favicon-small"/>
-
- <$text text={{!!bag-name}}/>
-
+
+ <$image source=`/wiki/${ [{!!bag-name}encodeuricomponent[]] }$/bags/${ [{!!bag-name}encodeuricomponent[]] }$/tiddlers/%24%3A%2Ffavicon.ico` class="mws-favicon-small"/>
+
+ <$text text={{!!bag-name}}/>
+
+
$genesis>
\end
@@ -62,24 +64,25 @@ title: MultiWikiServer Administration
\whitespace trim
-

+ <$image source=`/wiki/${ [{!!recipe-name}encodeuricomponent[]] }$/recipes/${ [{!!recipe-name}encodeuricomponent[]] }$/tiddlers/%24%3A%2Ffavicon.ico` class="mws-favicon"/>
@@ -91,7 +94,7 @@ title: MultiWikiServer Administration
These are the wikis available on this server. Click on a wiki to visit it in a new browser tab.
- <$list filter="[prefix[$:/state/multiwikiserver/recipes/]]">
+ <$list filter="[prefix[_multiwikiserver/recipes/]]">
-
<>
@@ -105,7 +108,7 @@ title: MultiWikiServer Administration
Bags
- <$list filter="[prefix[$:/state/multiwikiserver/bags/]]">
+ <$list filter="[prefix[_multiwikiserver/bags/]]">
-
<>
diff --git a/plugins/tiddlywiki/multiwikiserver/admin-ui/Styles.tid b/plugins/tiddlywiki/multiwikiserver/admin-ui/Styles.tid
index 11a5bab09..0a9013b84 100644
--- a/plugins/tiddlywiki/multiwikiserver/admin-ui/Styles.tid
+++ b/plugins/tiddlywiki/multiwikiserver/admin-ui/Styles.tid
@@ -53,10 +53,6 @@ Styles specific to the full screen layout
}
-.mws-wiki-card-extra {
-
-}
-
.mws-vertical-list {
list-style: none;
padding: 0;
@@ -79,6 +75,11 @@ Styles specific to the full screen layout
padding: 0 0.25em;
}
+.mws-bag-pill:hover {
+ background: <>;
+ foreground: <>;
+}
+
.mws-bag-pill-topmost {
background: <>;
}
@@ -87,17 +88,23 @@ Styles specific to the full screen layout
margin-left: 0.5em;
}
+.mws-bag-pill-link {
+ text-decoration: none;
+ color: currentcolor;
+}
+
+.mws-favicon.tc-image-loading, .mws-favicon-small.tc-image-loading,
.mws-favicon.tc-image-error, .mws-favicon-small.tc-image-error {
visibility: hidden;
}
.mws-favicon {
- max-width: 4em;
+ width: 4em;
max-height: 4em;
}
.mws-favicon-small {
vertical-align: text-bottom;
- max-width: 1em;
+ width: 1em;
max-height: 1em;
}
\ No newline at end of file
diff --git a/plugins/tiddlywiki/multiwikiserver/modules/init.js b/plugins/tiddlywiki/multiwikiserver/modules/init.js
index 4e747336f..75a520a3c 100644
--- a/plugins/tiddlywiki/multiwikiserver/modules/init.js
+++ b/plugins/tiddlywiki/multiwikiserver/modules/init.js
@@ -45,10 +45,10 @@ exports.startup = function() {
$tw.sqlTiddlerStore.createBag("bag-alpha");
$tw.sqlTiddlerStore.createBag("bag-beta");
$tw.sqlTiddlerStore.createBag("bag-gamma");
- $tw.sqlTiddlerStore.createRecipe("recipe-rho",["bag-alpha","bag-beta"]);
- $tw.sqlTiddlerStore.createRecipe("recipe-sigma",["bag-alpha","bag-gamma"]);
- $tw.sqlTiddlerStore.createRecipe("recipe-tau",["bag-alpha"]);
- $tw.sqlTiddlerStore.createRecipe("recipe-upsilon",["bag-alpha","bag-gamma","bag-beta"]);
+ $tw.sqlTiddlerStore.createRecipe("recipe-rho",["bag-alpha","bag-beta"],"First wiki");
+ $tw.sqlTiddlerStore.createRecipe("recipe-sigma",["bag-alpha","bag-gamma"],"Second Wiki");
+ $tw.sqlTiddlerStore.createRecipe("recipe-tau",["bag-alpha"],"Third Wiki");
+ $tw.sqlTiddlerStore.createRecipe("recipe-upsilon",["bag-alpha","bag-gamma","bag-beta"],"Fourth Wiki");
// Save tiddlers
$tw.sqlTiddlerStore.saveBagTiddler({title: "$:/SiteTitle",text: "Bag Alpha"},"bag-alpha");
$tw.sqlTiddlerStore.saveBagTiddler({title: "$:/SiteTitle",text: "Bag Beta"},"bag-beta");
diff --git a/plugins/tiddlywiki/multiwikiserver/modules/route-put-recipe-tiddler.js b/plugins/tiddlywiki/multiwikiserver/modules/route-put-recipe-tiddler.js
index c5ca2dd52..1e04d3094 100644
--- a/plugins/tiddlywiki/multiwikiserver/modules/route-put-recipe-tiddler.js
+++ b/plugins/tiddlywiki/multiwikiserver/modules/route-put-recipe-tiddler.js
@@ -40,10 +40,14 @@ exports.handler = function(request,response,state) {
// Require the recipe names to match
if(recipe_name === recipe_name_2) {
var result = $tw.sqlTiddlerStore.saveRecipeTiddler(fields,recipe_name);
- response.writeHead(204, "OK",{
- Etag: "\"" + result.bag_name + "/" + encodeURIComponent(title) + "/" + result.tiddler_id + ":\"",
- "Content-Type": "text/plain"
- });
+ if(result) {
+ response.writeHead(204, "OK",{
+ Etag: "\"" + result.bag_name + "/" + encodeURIComponent(title) + "/" + result.tiddler_id + ":\"",
+ "Content-Type": "text/plain"
+ });
+ } else {
+ response.writeHead(400);
+ }
response.end();
return;
}
diff --git a/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-database.js b/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-database.js
index 2a658cced..c6dca3aac 100644
--- a/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-database.js
+++ b/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-database.js
@@ -64,7 +64,8 @@ SqlTiddlerDatabase.prototype.createTables = function() {
-- Recipes have names...
CREATE TABLE IF NOT EXISTS recipes (
recipe_id INTEGER PRIMARY KEY AUTOINCREMENT,
- recipe_name TEXT UNIQUE
+ recipe_name TEXT UNIQUE,
+ description TEXT
)
`,`
-- ...and recipes also have an ordered list of bags
@@ -139,23 +140,27 @@ SqlTiddlerDatabase.prototype.createBag = function(bagname) {
});
};
+/*
+Returns array of {recipe_name:,description:}
+*/
SqlTiddlerDatabase.prototype.listRecipes = function() {
const rows = this.runStatementGetAll(`
- SELECT recipe_name
+ SELECT recipe_name, description
FROM recipes
ORDER BY recipe_name
`);
return rows;
};
-SqlTiddlerDatabase.prototype.createRecipe = function(recipename,bagnames) {
+SqlTiddlerDatabase.prototype.createRecipe = function(recipename,bagnames,description) {
// Run the queries
this.runStatement(`
-- Create the entry in the recipes table if required
- INSERT OR IGNORE INTO recipes (recipe_name)
- VALUES ($recipe_name)
+ INSERT OR IGNORE INTO recipes (recipe_name, description)
+ VALUES ($recipe_name, $description)
`,{
- recipe_name: recipename
+ recipe_name: recipename,
+ description: description
});
this.runStatement(`
-- Delete existing recipe_bags entries for this recipe
@@ -219,7 +224,7 @@ SqlTiddlerDatabase.prototype.saveBagTiddler = function(tiddlerFields,bagname) {
};
/*
-Returns {tiddler_id:,bag_name:}
+Returns {tiddler_id:,bag_name:} or null if the recipe is empty
*/
SqlTiddlerDatabase.prototype.saveRecipeTiddler = function(tiddlerFields,recipename) {
// Find the topmost bag in the recipe
@@ -241,6 +246,9 @@ SqlTiddlerDatabase.prototype.saveRecipeTiddler = function(tiddlerFields,recipena
`,{
recipe_name: recipename
});
+ if(!row) {
+ return null;
+ }
// Save the tiddler to the topmost bag
var info = this.saveBagTiddler(tiddlerFields,row.bag_name);
return {
diff --git a/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-store.js b/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-store.js
index 22c207dc6..f24eb5cea 100644
--- a/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-store.js
+++ b/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-store.js
@@ -23,7 +23,7 @@ adminWiki - reference to $tw.Wiki object into which entity state tiddlers should
function SqlTiddlerStore(options) {
options = options || {};
this.adminWiki = options.adminWiki || $tw.wiki;
- this.entityStateTiddlerPrefix = "$:/state/multiwikiserver/";
+ this.entityStateTiddlerPrefix = "_multiwikiserver/";
// Create the database
this.databasePath = options.databasePath || ":memory:";
var SqlTiddlerDatabase = require("$:/plugins/tiddlywiki/multiwikiserver/sql-tiddler-database.js").SqlTiddlerDatabase;
@@ -57,7 +57,7 @@ SqlTiddlerStore.prototype.updateAdminWiki = function() {
this.saveEntityStateTiddler({
title: "recipes/" + recipeInfo.recipe_name,
"recipe-name": recipeInfo.recipe_name,
- text: "",
+ text: recipeInfo.description,
list: $tw.utils.stringifyList(this.getRecipeBags(recipeInfo.recipe_name).map(bag_name => {
return this.entityStateTiddlerPrefix + "bags/" + bag_name;
}))
@@ -110,12 +110,14 @@ SqlTiddlerStore.prototype.listRecipes = function() {
return this.sqlTiddlerDatabase.listRecipes();
};
-SqlTiddlerStore.prototype.createRecipe = function(recipename,bagnames) {
- this.sqlTiddlerDatabase.createRecipe(recipename,bagnames);
+SqlTiddlerStore.prototype.createRecipe = function(recipename,bagnames,description) {
+ bagnames = bagnames || [];
+ description = description || "";
+ this.sqlTiddlerDatabase.createRecipe(recipename,bagnames,description);
this.saveEntityStateTiddler({
title: "recipes/" + recipename,
"recipe-name": recipename,
- text: "",
+ text: description,
list: $tw.utils.stringifyList(bagnames.map(bag_name => {
return this.entityStateTiddlerPrefix + "bags/" + bag_name;
}))
@@ -162,12 +164,16 @@ Returns {bag_name:, tiddler: {fields}, tiddler_id:}
*/
SqlTiddlerStore.prototype.getRecipeTiddler = function(title,recipename) {
var tiddlerInfo = this.sqlTiddlerDatabase.getRecipeTiddler(title,recipename);
- return Object.assign(
- {},
- tiddlerInfo,
- {
- tiddler: this.processOutgoingTiddler(tiddlerInfo.tiddler,tiddlerInfo.tiddler_id,tiddlerInfo.bag_name,recipename)
- });
+ if(tiddlerInfo) {
+ return Object.assign(
+ {},
+ tiddlerInfo,
+ {
+ tiddler: this.processOutgoingTiddler(tiddlerInfo.tiddler,tiddlerInfo.tiddler_id,tiddlerInfo.bag_name,recipename)
+ });
+ } else {
+ return null;
+ }
};
/*