Tiddlers - sgml/signature GitHub Wiki

Import Export

tiddler_decoupling:
  export_to_json:
    description: >
      Write tiddlers to a standalone JSON file for transfer and import on another device.
    steps:
      - Open your TiddlyWiki HTML file in a browser.
      - Navigate to Control Panel β†’ Tools β†’ Export Tiddlers.
      - Select export format: application/json.
      - Choose specific tiddlers or use a filter (e.g., tag[exportable]).
      - Click β€œExport” and save the resulting .json file.
      - Transfer the file via USB, cloud sync, or Git.
      - On the target device, open TiddlyWiki and go to Control Panel β†’ Tools β†’ Import.
      - Select the .json file and click β€œImport.”
      - Verify that metadata (title, tags, fields, timestamps) is preserved.

  export_to_csv_for_sqlite:
    description: >
      Export tiddlers from TiddlyWiki into CSV format for structured import into SQLite.
    steps:
      - Open TiddlyWiki and install the TiddlyTools/Export plugin or define a custom export macro.
      - Create a filtered list of tiddlers (e.g., [tag[exportable]] or [all[tiddlers]]).
      - Define an export template that outputs comma-separated values:
        template: |
          <$list filter="[all[tiddlers]]">
          <$text text=<<currentTiddler>>/title>>,<$text text=<<currentTiddler>>/text>>,<$text text=<<currentTiddler>>/tags>>
          </$list>
      - Copy the output and save it as a plain text file with `.csv` extension.
      - Clean up formatting using CLI tools (e.g., csvkit, awk) to ensure proper escaping.
      - Open SQLite and run:
        import_commands: |
          sqlite3 mywiki.db
          .mode csv
          .import tiddlers.csv tiddlers
      - Verify schema integrity and add indexes if needed for performance.

Tiddlers for Uniface Developers

Component-Based Architecture

  • Uniface: Uses forms, services, and reports as modular development units.
  • TiddlyWiki: Uses tiddlers as atomic content and logic blocks.

Metadata-Driven Configuration

  • Uniface: UI, data, and logic are largely defined through the repository’s metadata schema.
  • TiddlyWiki: Behavior and content are driven by tiddler fields and tags.

Separation of Concerns

  • Uniface: Implicitly separates model (entities), view (forms), and control (triggers).
  • TiddlyWiki: Encourages separation via templates/macros (view), filter expressions (model access), and JavaScript (controller behavior).

Scriptable Logic Layer

  • Uniface: ProcScript offers flow control, events, and CRUD hooks.
  • TiddlyWiki: JavaScript macros, filter expressions, and event hooks manage logic.

Data-Binding Paradigm

  • Uniface: Fields bind UI to the entity model.
  • TiddlyWiki: Transclusion and dynamic filters bind templates to data-driven tiddlers.

Event-Driven Interaction

  • Uniface: Trigger system responds to UI and lifecycle events.
  • TiddlyWiki: Handles clicks, changes, and navigation through event macros and widgets.

State Persistence

  • Uniface: Data persists via relational databases managed by Uniface runtime.
  • TiddlyWiki: Entire state (content + config) is embedded or persisted via storage adapters (filesystem, localStorage, etc.).

Runtime Interpretation

  • Uniface: Components are interpreted via Uniface VM at runtime.
  • TiddlyWiki: JavaScript engine interprets wiki logic live in the browser.

Low-Code/No-Code Flexibility

  • Uniface: Visual IDE and metadata tables reduce the need for manual code.

  • TiddlyWiki: Users can configure behavior using only tiddlers and wiki syntax.

  • Extensibility via Plugins or Modules

    • Uniface: Adds functionality through external libraries or Java/.NET integration.
    • TiddlyWiki: Extends capabilities via plugin tiddlers or custom JavaScript modules.

Schema.org mapping

{
  "@context": "https://schema.org",
  "@type": "MusicComposition",
  "name": "Seikilos Epitaph",
  "alternateName": "Seikilos Stele",
  "description": "An Ancient Greek inscription on marble preserving the oldest surviving complete musical composition, including lyrics and notation.",
  "creator": {
    "@type": "Person",
    "name": "Anonymous (attributed to Seikilos)"
  },
  "dateCreated": "1st–2nd century CE",
  "inLanguage": "Ancient Greek",
  "genre": "Song",
  "material": "Marble",
  "locationCreated": {
    "@type": "Place",
    "name": "Tralles (modern AydΔ±n, Turkey)"
  },
  "workExample": {
    "@type": "ImageObject",
    "contentUrl": "https://upload.wikimedia.org/wikipedia/commons/1/12/Seikilos_epitaph.jpg",
    "caption": "The marble stele bearing the Seikilos Epitaph"
  },
  "identifier": "National Museum of Denmark, inv. 14897",
  "sameAs": "https://en.wikipedia.org/wiki/Seikilos_epitaph"
}

Supersetting

  • MPAA rating
  • Gender
  • Gas Price
  • Culture Vulture
  • Edutainment
  • After School Special moment
  • Soundtrack Rating

Subsetting

The copyright of TiddlyWiki is held in trust

Globals

Global CSS

  • .tc-body /* Main body wrapper */
  • .tc-page-container /* Contains the entire visible page */
  • .tc-sidebar /* Sidebar container */
  • .tc-story-river /* Main content area where tiddlers appear */
  • .tc-header /* Top header bar */
  • .tc-footer /* Footer area */
  • .tc-hidden /* Hides elements */
  • .tc-vertical /* Vertical layout */
  • .tc-horizontal /* Horizontal layout */
  • .tc-block /* Block-level layout */
  • .tc-inline /* Inline layout */
  • .tc-clear /* Clear floats */
  • .tc-tab-buttons /* Tab navigation buttons */
  • .tc-tab-content /* Tab content area */
  • .tc-button /* Generic button styling */
  • .tc-drop-down /* Dropdown menus */
  • .tc-popup /* Popups (e.g., tag selectors, menus) */
  • .tc-modal /* Modal dialogs */
  • .tc-alert /* Alert messages */
  • .tc-sidebar-scrollable /* Scrollable area in sidebar */
  • .tc-sidebar-tabs /* Tabs in the sidebar */
  • .tc-sidebar-header /* Header of the sidebar */
  • .tc-sidebar-footer /* Footer of the sidebar */

Global JS

  • $tw.wiki // Access to the wiki store and tiddlers
  • $tw.rootWidget // Root widget tree (useful for traversing UI)
  • $tw.modules // Registry of loaded modules
  • $tw.utils // Utility functions (e.g., DOM, string, array helpers)
  • $tw.notifier // Trigger UI notifications

CSS Reset

/* Layout Containers */
.tc-body,
.tc-page-container,
.tc-sidebar,
.tc-story-river {
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
}

/* Header & Footer */
.tc-header,
.tc-footer,
.tc-sidebar-header,
.tc-sidebar-footer {
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
}

/* Visibility Control */
.tc-hidden {
  display: none !important;
  visibility: hidden;
}

/* Layout Modifiers */
.tc-vertical {
  display: block;
}

.tc-horizontal {
  display: block;
}

.tc-block {
  display: block;
}

.tc-inline {
  display: inline;
}

.tc-clear {
  clear: both;
}

/* Tab System */
.tc-tab-buttons,
.tc-tab-content {
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
}

/* Interactive Elements */
.tc-button,
.tc-drop-down {
  all: unset;
  display: inline-block;
  cursor: pointer;
  font: inherit;
  color: inherit;
  background: none;
  border: none;
}

/* Overlay Elements */
.tc-popup,
.tc-modal,
.tc-alert {
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
}

/* Sidebar Scrollable & Tabs */
.tc-sidebar-scrollable,
.tc-sidebar-tabs {
  overflow: auto;
  margin: 0;
  padding: 0;
}

Reset Process

Installation

  1. Open your TiddlyWiki.

  2. Click the "+" button to create a new tiddler.

  3. Set the title to:

    $:/styles/ResetCSS

  4. Add the following tag:

    $:/tags/Stylesheet

  5. Paste the CSS reset code into the body. Example:

    .tc-body, .tc-page-container, .tc-sidebar, .tc-story-river { margin: 0; padding: 0; box-sizing: border-box; font: inherit; color: inherit; background: none; }

    .tc-hidden { display: none !important; visibility: hidden; }

    .tc-button { all: unset; display: inline-block; cursor: pointer; }

    /* Add additional .tc-* class resets as needed */

  6. Click "Done" to save the tiddler.

  7. Rename the file to be index.html, and replace the old index.html

Saving

  • If using a single-file wiki, click "Save" or download the updated file.
  • If using TiddlyWiki on Node.js, changes are saved automatically.

Testing

After saving:

  • Refresh the wiki.
  • Use browser developer tools to inspect layout elements:
    • .tc-header
    • .tc-footer
    • .tc-sidebar
    • .tc-story-river
    • .tc-button
    • .tc-tab-buttons
    • .tc-popup
    • .tc-modal

Verify that:

  • Margins and paddings are removed.
  • Fonts and colors are inherited.
  • Hidden elements are suppressed correctly.

Debugging

Issue Diagnosis Fix Strategy
Styles not applying Missing $:/tags/Stylesheet tag Retag and refresh
Conflicts with theme styles Theme overrides reset Use !important selectively
Widget rendering broken Overuse of all: unset Scope resets to layout primitives only
Sidebar scroll broken Missing overflow on .tc-sidebar-scrollable Add overflow: auto
Reset not loading Tiddler not saved or misnamed Re-save or rename

Extension Ideas

  • Create a diagnostic overlay tiddler to visualize layout boundaries.
  • Use $tw.utils.domContainsClass() to trace class usage.
  • Map .tc-* classes to widget origins using $tw.rootWidget.

Global JS objects:

  • $tw.wiki
  • $tw.rootWidget
  • $tw.modules
  • $tw.utils
  • $tw.notifier

Util Methods

Method Description Documentation / Source URL
extend(target, ...sources) Deep merges multiple objects into the target Source
each(obj, callback) Iterates over arrays or objects Source
map(array, callback) Maps over an array Source
filter(array, callback) Filters an array based on a predicate Source
pushTop(array, value) Pushes a value to the top of an array if not already present Source
escapeHtml(str) Escapes HTML entities Source
unescapeHtml(str) Unescapes HTML entities Source
escapeRegExp(str) Escapes RegExp special characters Source
decodeURIComponentSafe(str) Decodes URI component safely Source
stringifyList(list) Converts array to space-separated string Source
hasClass(el, className) Checks if element has a class Source
addClass(el, className) Adds a class to an element Source
removeClass(el, className) Removes a class from an element Source
toggleClass(el, className) Toggles a class on an element Source
domContains(parent, child) Checks if parent contains child node Source
isArray(obj) Checks if value is an array Source
isPlainObject(obj) Checks if value is a plain object Source
isFunction(obj) Checks if value is a function Source
isDate(obj) Checks if value is a Date object Source
parseFields(text) Parses field string into object Source
stringifyFields(fields) Converts field object to string Source
parseJSONSafe(str, fallback) Parses JSON with fallback Source
generateHash(str) Generates a hash from a string Source
getFileExtension(filename) Extracts file extension from filename Source

Defaults

JavaScript API

api_methods:
  - component: "$tw"
    member_method: "version"
    type: "Property"
    description: "The TiddlyWiki version string (e.g., \"5.2.3\")."
  - component: "$tw"
    member_method: "boot"
    type: "Property"
    description: "Boot data including the initial set of tiddlers and configuration loaded during startup."
  - component: "$tw"
    member_method: "wiki"
    type: "Object"
    description: "The main tiddler store that provides methods to add, retrieve, update, delete, and filter tiddlers."
  - component: "$tw"
    member_method: "config"
    type: "Object"
    description: "Global configuration settings (paths, defaults, and behavior options) for TiddlyWiki."
  - component: "$tw"
    member_method: "language"
    type: "Object"
    description: "Contains translation strings and localization settings."
  - component: "$tw"
    member_method: "utils"
    type: "Object"
    description: "A set of utility functions (e.g., object manipulation, deep copy, text parsing, and encoding/decoding)."
  - component: "$tw"
    member_method: "hooks"
    type: "Object"
    description: "Functions to add (`add(name,callback)`) and invoke (`invoke(name, args)`) hook callbacks for events."
  - component: "$tw"
    member_method: "modules"
    type: "Object"
    description: "The module management system for registering and loading modules."
  - component: "$tw"
    member_method: "syncer"
    type: "Object"
    description: "Contains methods for synchronizing tiddlers with external storage (e.g., via the sync protocol)."
  - component: "$tw.boot"
    member_method: "tiddlers"
    type: "Property"
    description: "The collection of boot tiddlers loaded from the source file."
  - component: "$tw.boot"
    member_method: "startup"
    type: "Property"
    description: "Startup configuration and bootstrapping data."
  - component: "$tw.wiki"
    member_method: "getTiddler(title)"
    type: "Function"
    description: "Returns the tiddler object for the given title, or `undefined` if it does not exist."
  - component: "$tw.wiki"
    member_method: "getTiddlerText(title, [defaultText])"
    type: "Function"
    description: "Retrieves the text field of the tiddler; returns a default value if the tiddler is missing."
  - component: "$tw.wiki"
    member_method: "getTiddlerField(title, field, [defaultValue])"
    type: "Function"
    description: "Retrieves a specific field (e.g., 'tags', 'modified') from a tiddler; returns a default if absent."
  - component: "$tw.wiki"
    member_method: "addTiddler(tiddler)"
    type: "Function"
    description: "Adds a new tiddler or updates an existing one."
  - component: "$tw.wiki"
    member_method: "deleteTiddler(title)"
    type: "Function"
    description: "Removes the specified tiddler from the wiki store."
  - component: "$tw.wiki"
    member_method: "filterTiddlers(filterExpression)"
    type: "Function"
    description: "Applies a filter expression and returns an array of tiddler titles that match the criteria."
  - component: "$tw.wiki"
    member_method: "each(callback)"
    type: "Function"
    description: "Iterates over all tiddlers in the store, calling the callback function for each one."
  - component: "$tw.wiki"
    member_method: "isShadowTiddler(title)"
    type: "Function"
    description: "Returns a boolean indicating whether a tiddler is a shadow tiddler."
  - component: "$tw.wiki"
    member_method: "getShadowTiddler(title)"
    type: "Function"
    description: "Retrieves the shadow version of a tiddler if available."
  - component: "$tw.wiki"
    member_method: "getChangeCount()"
    type: "Function"
    description: "Returns the total number of changes made to the wiki (useful for caching or sync checks)."
  - component: "$tw.utils"
    member_method: "deepCopy(object)"
    type: "Function"
    description: "Creates a deep copy of the provided object (helpful for cloning tiddler data)."
  - component: "$tw.utils"
    member_method: "extend(target, source)"
    type: "Function"
    description: "Merges properties from the source object into the target object."
  - component: "$tw.utils"
    member_method: "stringify(object)"
    type: "Function"
    description: "Converts an object to a JSON string."
  - component: "$tw.utils"
    member_method: "parseText(source, type, [options])"
    type: "Function"
    description: "Parses source text (for example, WikiText) into a structured parse tree according to the specified type."
  - component: "$tw.hooks"
    member_method: "add(name, callback)"
    type: "Function"
    description: "Registers a callback function on a given hook name."
  - component: "$tw.hooks"
    member_method: "invoke(name, args)"
    type: "Function"
    description: "Invokes all functions registered for the specified hook name, passing in any provided arguments."
  - component: "$tw.modules"
    member_method: "register(moduleType, moduleName, module)"
    type: "Function"
    description: "Registers a new module under a specific type and name for use by the TiddlyWiki system."
  - component: "$tw.syncer"
    member_method: "sync(data, callback)"
    type: "Function"
    description: "Initiates the synchronization process of tiddlers with an external storage source."

CSS Stylesheet

classes:
  - class_name: ".tc-tiddler-frame"
    description: "Styles the outer container (frame) for each tiddler in the story riverβ€”including borders, padding, and margins."
  - class_name: ".tc-tiddler-title"
    description: "Applies to the header or title bar of a tiddler, controlling the appearance of its title text."
  - class_name: ".tc-tiddler-body"
    description: "Styles the main content area of a tiddler where text, widgets, and other content are rendered."
  - class_name: ".tc-tiddler-controls"
    description: "Encapsulates the control buttons (like edit, close, and options) that appear on a tiddler."
  - class_name: ".tc-story-river"
    description: "The container that holds and organizes all open tiddlers within the main display area."
  - class_name: ".tc-sidebar"
    description: "Defines the visual appearance of the sidebar, typically used for navigation and metadata."
  - class_name: ".tc-sidebar-header"
    description: "Styles the header area of the sidebar, which may include titles or logos."
  - class_name: ".tc-sidebar-tabs"
    description: "Styles the tabbed navigation within the sidebar that lets users switch between different panels."
  - class_name: ".tc-tag-list"
    description: "Used for styling the list of tags that appear in or alongside a tiddler."
  - class_name: ".tc-button"
    description: "A generic class for styling interactive buttons throughout the TiddlyWiki interface."
  - class_name: ".tc-edit-texteditor"
    description: "Styles the text editor used when modifying the content of a tiddler."
  - class_name: ".tc-dropzone"
    description: "Defines the look of the drag-and-drop overlay used for file uploads or widget repositioning."
  - class_name: ".tc-notification"
    description: "Styles pop-up notifications or alert messages shown to the user."
  - class_name: ".tc-page-controls"
    description: "Contains global controls (such as save, settings, and other menu buttons) at the page level."
  - class_name: ".tc-search-input"
    description: "Applies styling to the search box where text queries are entered by the user."
  - class_name: ".tc-search-results"
    description: "Styles the container that displays search results after a query is executed."
  - class_name: ".tc-menu"
    description: "Used for styling dropdown menus or context menus in the TiddlyWiki interface."
  - class_name: ".tc-popup"
    description: "Styles pop-up elements that display transient information or additional options."
  - class_name: ".tc-tab"
    description: "Applies to individual tabs whether in the sidebar or in other tabbed interface elements."
  - class_name: ".tc-message-area"
    description: "Styles the area where system messages, status bars, or user alerts are shown."

Tagging Plugins

Platform Project Name Purpose / Highlights Last Update GitHub URL
TiddlyWiki TW5-TiddlyMap Visualizes semantic relationships via graph mapping Nov 2024 GitHub
TiddlyWiki TW5-JsonMangler Parses nested JSON into structured tiddlers Jan 2025 GitHub
TiddlyWiki tw5-kin-filter Semantic filtering for hierarchical relationships Oct 2024 GitHub

System Tiddlers

Macros

Definition Tiddler

title: GoodbyeOnUnload
type: text/vnd.tiddlywiki
tags: $:/tags/StartupAction

\whitespace trim
<$addmessage $message="th-startup"/>
<$macrocall $name="add-beforeunload-hook"/>

Caller Tiddler

title: $:/macros/add-beforeunload-hook
type: text/vnd.tiddlywiki

\whitespace trim
\define add-beforeunload-hook()
<script>
// Reference: https://tiddlywiki.com/static/Macros.html

window.addEventListener("beforeunload", function(event) {
  alert("Goodbye");
});

</script>
\end

Lifecycle Hooks

tiddler_hooks:
  - name: "th-saving-tiddler"
    description: "Triggered before a tiddler is saved. Allows modification or validation before committing changes."
  - name: "th-saved-tiddler"
    description: "Triggered after a tiddler is successfully saved."
  - name: "th-deleting-tiddler"
    description: "Triggered before a tiddler is deleted. Can be used to prevent deletion or log events."
  - name: "th-deleted-tiddler"
    description: "Triggered after a tiddler is deleted."
  - name: "th-edit-tiddler"
    description: "Triggered when a tiddler enters edit mode."
  - name: "th-new-tiddler"
    description: "Triggered when a new tiddler is created."
  - name: "th-renaming-tiddler"
    description: "Triggered before a tiddler is renamed."
  - name: "th-renamed-tiddler"
    description: "Triggered after a tiddler is renamed."
  - name: "th-loading-tiddler"
    description: "Triggered when a tiddler is being loaded from storage."
  - name: "th-loaded-tiddler"
    description: "Triggered after a tiddler has been loaded."

User Defined Custom Lifecycle Hooks

Create a system tiddler: $:/plugins/custom/customHookPlugin, then define the custom hook:

Read-Only Mode Hook

plugin:
  name: "readOnlyModeBootHook"
  type: "application/javascript"
  description: "Forces all tiddlers into read-only mode by disabling editing actions at startup."
  implementation:
    - step: "Define the plugin"
      code: |
        (function() {
          "use strict";
          exports.name = "readOnlyModeBootHook";
          exports.platforms = ["browser"];
          exports.after = ["startup"];
          exports.startup = function() {
            // Hook into TiddlyWiki boot sequence
            // Reference: Official Hook Documentation - https://tiddlywiki.com/dev/static/HookMechanism.html
            $tw.hooks.addHook("th-startup", function() {
              $tw.wiki.addTiddler({title: "$:/status/IsReadOnly", text: "yes"});
              console.log("TiddlyWiki started in read-only mode.");
            });

            // Block tiddler editing actions globally
            $tw.hooks.addHook("th-edit-tiddler", function(title) {
              console.log("Editing blocked for:", title);
              alert("This wiki is in read-only mode. Editing is disabled.");
              return false;
            });
          };
        })();
    - step: "Set read-only mode at startup"
      code: |
        $tw.wiki.addTiddler({title: "$:/status/IsReadOnly", text: "yes"});
    - step: "Block all tiddler editing actions"
      code: |
        $tw.hooks.addHook("th-edit-tiddler", function(title) {
          console.log("Editing blocked for:", title);
          alert("This wiki is in read-only mode. Editing is disabled.");
          return false;
        });
    - step: "Verify plugin installation"
      instruction: "Reload TiddlyWiki (`Ctrl + Shift + R`), try to edit a tiddler, and confirm editing is blocked."
    - step: "Extend functionality"
      options:
        - "Add a system tiddler (`$:/config/EnableEditing`) to allow conditional toggling."
        - "Log blocked edits to a hidden tiddler for tracking attempts."
        - "Modify UI elements to visually indicate read-only mode."

No Navigation Hook

plugin:
  name: "replaceSidebarWithComment"
  type: "application/javascript"
  description: "Removes sidebar and main navigation at startup by replacing children with a date-stamped comment."
  implementation:
    - step: "Define the plugin"
      code: |
        (function() {
          "use strict";
          exports.name = "replaceSidebarWithComment";
          exports.platforms = ["browser"];
          exports.after = ["startup"];
          exports.startup = function() {
            // Hook into TiddlyWiki startup
            // Reference: Official Hook Documentation - https://tiddlywiki.com/dev/static/HookMechanism.html
            $tw.hooks.addHook("th-startup", function() {
              var elements = document.querySelectorAll(".tc-sidebar, .tc-page-controls");
              var currentDate = new Date().toISOString().split("T")[0]; // Get YYYY-MM-DD format
              
              elements.forEach(function(el) {
                el.replaceChildren(document.createComment("Removed on: " + currentDate));
              });

              console.log("Sidebar and navigation replaced with comment node: " + currentDate);
            });
          };
        })();
    - step: "Replace children of sidebar and navigation"
      code: |
        var currentDate = new Date().toISOString().split("T")[0]; 
        var elements = document.querySelectorAll(".tc-sidebar, .tc-page-controls");
        elements.forEach(function(el) {
          el.replaceChildren(document.createComment("Removed on: " + currentDate));
        });
    - step: "Verify plugin installation"
      instruction: "Reload TiddlyWiki (`Ctrl + Shift + R`), inspect the DOM (`F12 > Elements`), and confirm sidebar and navigation are replaced with a comment."
    - step: "Extend functionality"
      options:
        - "Add a toggle mechanism to restore the sidebar."
        - "Use a system tiddler (`$:/config/ReplaceSidebarWithComment`) to conditionally apply removal."
        - "Log the removal action into a tiddler."

Save State Hook

plugin:
  name: "customHookPlugin"
  type: "application/javascript"
  description: "Adds a custom lifecycle hook for triggering actions when a tiddler is processed."
  implementation:
    - step: "Define the plugin structure"
      code: |
        (function() {
          "use strict";
          exports.name = "customHookPlugin";
          exports.platforms = ["browser"];
          exports.after = ["startup"];
          exports.startup = function() {
            // Define the custom hook
            $tw.hooks.addHook("th-custom-action", function(title) {
              console.log("Custom hook activated for:", title);
              alert("Custom action executed for: " + title);
            });
          };
        })();
    - step: "Manually trigger the hook"
      code: |
        $tw.hooks.invokeHook("th-custom-action", "MyTiddler");
    - step: "Attach hook to tiddler saving lifecycle"
      code: |
        $tw.hooks.addHook("th-saving-tiddler", function(title) {
          $tw.hooks.invokeHook("th-custom-action", title);
        });
    - step: "Prevent tiddler saving via hook"
      code: |
        $tw.hooks.addHook("th-saving-tiddler", function(title) {
          alert("Saving is blocked for: " + title);
          return false;
        });
    - step: "Modify tiddler content before saving"
      code: |
        $tw.hooks.addHook("th-saving-tiddler", function(title, fields) {
          fields.text += "\n\n-- Updated automatically.";
          return fields;
        });
    - step: "Verify plugin installation"
      instruction: "Reload TiddlyWiki (`Ctrl + Shift + R`), open Developer Console (`F12`), and manually trigger the hook to confirm execution."
    - step: "Extend hook for advanced usage"
      options:
        - "Attach it to UI elements (buttons, widgets)."
        - "Log actions to a database or file."
        - "Modify appearance based on hook execution."

Dynamically Created Tiddler Hook

plugin:
  name: "createTiddlerOnStartup"
  type: "application/javascript"
  description: "Generates a new tiddler at startup using a JSON argument."
  implementation:
    - step: "Define the plugin"
      code: |
        (function() {
          "use strict";
          exports.name = "createTiddlerOnStartup";
          exports.platforms = ["browser"];
          exports.after = ["startup"];
          exports.startup = function() {
            // Hook into TiddlyWiki startup
            // Reference: Official Hook Documentation - https://tiddlywiki.com/dev/static/HookMechanism.html

            // JSON Schema for the generated tiddler
            /*
              {
                "title": "string",          // Required: Unique identifier for the tiddler
                "text": "string",           // Required: Content of the tiddler
                "tags": "string",           // Optional: Space-separated list of tags
                "creator": "string",        // Optional: Author name
                "modified": "string",       // Optional: Last modified timestamp (YYYYMMDDHHMMSS)
                "created": "string"         // Optional: Creation timestamp (YYYYMMDDHHMMSS)
              }
            */

            var jsonData = {
              title: "GeneratedTiddler",
              text: "This tiddler was automatically created on startup.",
              tags: "auto-generated",
              creator: "System",
              modified: new Date().toISOString().replace(/\D/g, "").slice(0, 14),
              created: new Date().toISOString().replace(/\D/g, "").slice(0, 14)
            };

            $tw.wiki.addTiddler(new $tw.Tiddler(jsonData));
            console.log("Generated tiddler:", jsonData.title);
          };
        })();
    - step: "Generate a new tiddler from JSON"
      code: |
        var jsonData = {
          title: "GeneratedTiddler",
          text: "This tiddler was automatically created on startup.",
          tags: "auto-generated",
          creator: "System",
          modified: new Date().toISOString().replace(/\D/g, "").slice(0, 14),
          created: new Date().toISOString().replace(/\D/g, "").slice(0, 14)
        };
        $tw.wiki.addTiddler(new $tw.Tiddler(jsonData));
    - step: "Verify plugin installation"
      instruction: "Reload TiddlyWiki (`Ctrl + Shift + R`), search for `GeneratedTiddler`, and confirm its content."
    - step: "Extend functionality"
      options:
        - "Modify the JSON argument to include custom fields like `status`, `priority`, or `category`."
        - "Use a system tiddler (`$:/config/CreateTiddlerData`) to dynamically load JSON at startup."
        - "Log the creation action into a hidden tiddler for tracking."

Examples

JSON Tiddler

MIME Types

Theming

Process

Step 1

/* title: $:/themes/atoz/minimalism */
{
  "title": "$:/themes/atoz/minimalism",
  "type": "application/x-tiddler-dictionary",
  "tags": "$:/theme",
  "description": "A minimalist theme overlay for subtle customization"
}

Step 2

/* Hide sidebar and tweak font sizes */
/* title: $:/themes/atoz/minimalism/styles/core */
.tc-sidebar {
  display: none;
}

body {
  font-family: "Inter", sans-serif;
  font-size: 16px;
}

.tc-tiddler-title {
  font-weight: 500;
  color: #444;
}

Step 3

{
  "title": "$:/themes/atoz/minimalism/metadata",
  "type": "application/json",
  "tags": "$:/tags/Theme",
  "name": "Minimal Overlays",
  "description": "Subtle visual tweaks using stylesheet layering"
}

File Structure

Component Title Format Tags Purpose / Behavior
Theme Tiddler $:/themes/<author-or-project>/<ThemeName>/Theme $:/tags/Theme Makes the theme selectable in Appearance settings
Stylesheet Tiddler $:/themes/<author-or-project>/<ThemeName>/Stylesheet $:/tags/Stylesheet Loads CSS when theme is active; scoped styling
Color Palette $:/themes/<author-or-project>/<ThemeName>/ColorPalette $:/tags/ColorPalette Loads palette variables used by theme and widgets

Creation

Step No. Task Description Tips
1 Understand Theme Architecture Learn how themes are structured using tagged tiddlers like Stylesheet, ColorPalette, and Theme. Explore core theme tiddlers in $:/themes/tiddlywiki/vanilla for inspiration.
2 Create Stylesheet Make a tiddler tagged $:/tags/Stylesheet and set type: text/css to define custom styles. Use specific selectors like body.tc-body to override defaults.
3 Define Color Palette (Optional) Create a tiddler tagged $:/tags/ColorPalette with color fields like foreground, background. Reference fields using $color$ in CSS for dynamic theming.
4 Override Page Template (Optional) Clone and modify $:/core/ui/PageTemplate to change layout structure. Save under a new title and link it from your theme metadata if needed.
5 Create Theme Metadata Tag the theme with $:/tags/Theme to bind stylesheets and palette into a selectable theme. Use a unique title and caption for recognition in Appearance settings.
6 Bind Stylesheet and Palette Ensure your theme tiddler references your stylesheet and palette via tagging. Confirm your stylesheet is tagged $:/tags/Stylesheet and palette as $:/tags/ColorPalette.
7 Activate Your Theme Go to Control Panel β†’ Appearance β†’ Theme and select your custom theme from the dropdown. If your theme doesn’t appear, double-check tags and tiddler naming consistency.

Editing Themes

Step Action Notes
Locate Theme Tiddler Open Control Panel β†’ Appearance β†’ Theme and search for the theme (e.g. $:/themes/xyz) This is the central metadata tiddler tagged $:/tags/Theme
Edit Theme Metadata Update fields like caption, description, or add a custom version Affects how the theme appears in the UI and supports changelog tracking
Modify Stylesheet Find and edit $:/themes/.../Stylesheet Adjust layout, spacing, or design elements directly via CSS
Update Color Palette Edit $:/themes/.../ColorPalette to change foreground, background, etc. These values are referenced by widgets and layout components
Apply Changes Save tiddlers and refresh the wiki Your changes will take effect instantly across pages and widgets
Maintain Selectable Status Ensure your theme tiddler is still tagged with $:/tags/Theme Required for the theme to remain selectable in the Appearance panel
Plugin Consideration If theme is bundled as a plugin, unpack it first to make edits Changes may be overwritten if the plugin is updated later

Delete a Theme

Step Action Notes
Open Plugins Panel Go to Control Panel β†’ Plugins Lists all installed plugins, including themes
Locate Theme Plugin Search for the theme (e.g. $:/themes/tiddlywiki/vanilla) Themes are stored as plugin tiddlers
Open Plugin Tiddler Click the theme entry to view its contents Reveals metadata and bundled components
Delete Theme Click More β†’ Delete within the plugin tiddler Removes the theme from the wiki
Save & Refresh Save changes and reload the wiki Ensures theme is fully unloaded and UI updates accordingly

Notes:

  • If the theme was active, TiddlyWiki will revert to the default or prompt for another.
  • For Node.js installs, deletion might also require removing files from the tiddlers/ or plugin folder manually.
  • For dynamic loading versions (v5.1.22+), no full reload is required after deletion.

Guides

Macros

Core Files

core_ui_files:
  PageTemplate:
    description: >
      Defines the overall HTML structure of the wiki, including elements like the sidebar, toolbar, and content area.
    purpose: >
      Change the layout and structure of the TiddlyWiki interface.
  
  ViewTemplate:
    description: >
      Determines how individual tiddlers are displayed when viewed.
    purpose: >
      Alter the presentation of tiddler content, such as adding custom styling or additional metadata.
  
  EditTemplate:
    description: >
      Dictates the appearance and structure of tiddlers when they are in edit mode.
    purpose: >
      Change the edit interface, such as adding new input fields or buttons.
  
  ControlPanel:
    description: >
      Includes the settings and configuration options available to users.
    purpose: >
      Add or remove configuration options in the Control Panel.
  
  Styles:
    description: >
      Contains CSS files that define the visual styling of the TiddlyWiki interface.
    purpose: >
      Change the appearance of various UI elements, such as fonts, colors, and layouts.
  
  Toolbar:
    description: >
      Defines the toolbar that appears at the top of each tiddler.
    purpose: >
      Add, remove, or modify toolbar buttons and functionality.
  
  StoryTiddlerTemplate:
    description: >
      Determines the structure and presentation of story tiddlers within the main content area.
    purpose: >
      Change how these tiddlers are rendered.
  
  ImportTiddlers:
    description: >
      Manages the interface for importing tiddlers into the wiki.
    purpose: >
      Change the import process and presentation.

Tagging

Step Action Purpose / Behavior
Define Tag Tiddler Create a tiddler (e.g. ProjectA) that will act as the "foreign key" Serves as the parent or category tiddler
Tag Related Tiddlers Add ProjectA to the tags field of related tiddlers Establishes a one-to-many relationship (e.g. tasks belonging to ProjectA)
Use tagging[] Filter Apply [tagging[ProjectA]] to list all tiddlers tagged with ProjectA Retrieves all "child" tiddlers linked to the "foreign key"
Nest Tags for Hierarchies Tag ProjectA with ClientX to create multi-level relationships Enables hierarchical structures like ClientX > ProjectA > Task1
Add Metadata to Tag Tiddler Include fields like type, status, or owner in ProjectA Enriches the foreign key with descriptive data
Use tag[] for Reverse Lookup Apply [tag[Task1]] to find its parent tag(s) Allows reverse traversal from child to parent
Display with Tag Pills Enable tag pills in UI to navigate between related tiddlers Provides clickable links for intuitive navigation

Global Styles

Create a tiddler tagged with $:/tags/Stylesheet to apply global styles.

title: $:/themes/MyCustomTheme
tags: $:/tags/Stylesheet
type: text/css

/* Masonry-style layout */
.masonry-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  grid-gap: 10px;
}

.masonry-item {
  background: #fff;
  padding: 10px;
  border-radius: 5px;
  box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
}

TailwindCSS

setup:
  - description: Create a new TiddlyWiki project or open your existing project.
  - description: Create a new tiddler named `tailwind.css`.

add_tailwindcss:
  description: Add TailwindCSS to your project.
  steps:
    - name: Add TailwindCSS
      code: |
        @import url('https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css');

customize_tailwindcss:
  description: Customize TailwindCSS in `tailwind.css`.
  example:
    - name: Add Custom Styles
      code: |
        @import url('https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css');
        .my-custom-style {
          background-color: #f0f0f0;
        }

configure_tiddlywiki:
  description: Configure TiddlyWiki to use the stylesheet.
  steps:
    - name: Open `$:/core/ui/PageTemplate` tiddler
    - name: Add link in `<head>` section
      code: |
        <link rel="stylesheet" href="$:/path/to/tailwind.css">
      note: Replace `$:/path/to/tailwind.css` with the actual path to your `tailwind.css` tiddler.

apply_tailwindcss:
  description: Apply TailwindCSS classes to tiddlers.
  steps:
    - name: Use TailwindCSS utility classes in TiddlyWiki content
      example: Add classes like `bg-gray-100` to apply background colors.

preview_adjust:
  description: Save changes and preview your TiddlyWiki.
  steps:
    - name: Adjust styles as needed
      result: Achieve the desired look and feel.
  • File: /core/ui/PageTemplate

Themes

Base Theme

  • .tc-theme-light /* Light theme base */
  • .tc-theme-dark /* Dark theme base */
  • .tc-color-scheme /* Applied for color palette overrides */

Theme HTML Customization

To ensure that tiddlers use the masonry-container class, modify the ViewTemplate or use a custom template.

title: $:/themes/MyCustomViewTemplate
type: text/vnd.tiddlywiki

<div class="masonry-container">
  <$list filter="[tag[Masonry]]">
    <div class="masonry-item">
      <$transclude />
    </div>
  </$list>
</div>

Applying the Theme

  • Open $:/ControlPanel

  • Navigate to Appearance β†’ Theme

  • Select $:/themes/MyCustomTheme

Using Tag-Based Styling

If you want only specific tiddlers to adopt the masonry layout, tag them with Masonry and use a filter:

.tc-tiddler-frame[tag="Masonry"] {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}

Transclusion

<!-- 
    The <$transclude /> widget in TiddlyWiki dynamically embeds the content of another tiddler. 
    It allows for modular content reuse without duplication. 
    More details: https://tiddlywiki.com/#Transclusion
-->
<$transclude tiddler="MyTiddler" />

Keyboard Shortcuts

Shortcut Action Documentation URL
Ctrl + Enter Confirm changes to a tiddler Link
Esc Discard changes to a tiddler Link
Ctrl + B Apply bold formatting Link
Ctrl + I Apply italic formatting Link
Ctrl + L Create a wikitext link Link
Ctrl + Shift + L Apply bulleted list formatting Link
Ctrl + Shift + N Apply numbered list formatting Link
Ctrl + Shift + M Apply monospaced block formatting Link
Alt + N Create a new tiddler Link
Alt + J Create a new journal tiddler Link
Ctrl + Shift + F Focus sidebar search Link
Shift + Alt + S Toggle sidebar visibility Link
Ctrl + Shift + A Open advanced search Link
Ctrl + Alt + C Open control panel Link

Search Operators

Status Pages

[all[tiddlers]prefix[$:/status/]]

Config Pages

[all[tiddlers]prefix[$:/config/]]

Static Site Generation

Step Action Command / Details
1. Install TiddlyWiki Install TiddlyWiki globally via npm. npm install -g tiddlywiki
2. Initialize a Wiki Create a new wiki in the desired directory. tiddlywiki mywiki --init server
3. Populate the Wiki Add tiddlers via web interface or manually. tiddlywiki mywiki --listen (for editing via browser)
4. Generate Static Output (Single Page) Render all tiddlers into a single index.html. tiddlywiki mywiki --output static_site --render '.' 'index.html' 'text/html'
5. Generate Static Output (Multi-Page) Export each tiddler separately as static HTML. tiddlywiki mywiki --output static_site --render '.' '$:/core/templates/static.tiddler.html' 'text/html'
6. Review and Adjust Output Verify static assets, styles, and structure. Manually inspect static_site/ directory.
7. Serve Locally Launch a simple local HTTP server. npx serve static_site
8. Deploy to GitHub Pages Push static_site/ folder to a gh-pages branch. Use git push & enable Pages in repository settings.
9. Deploy to Netlify Upload the static site via Netlify CLI. netlify deploy --dir static_site
10. Deploy to Web Server Upload files via FTP or SSH. Use preferred FTP/SSH method.

Guides

Navigation

open_tiddlers:
  methods:
    - name: Search Box
      description: >
        Use the search box in the TiddlyWiki interface to search for the name of the tiddler you want to open.
        As you type, TiddlyWiki will suggest matching tiddlers. Click on the desired tiddler from the suggestions to open it.

    - name: Links
      description: >
        Create links to specific tiddlers within other tiddlers using the double square brackets syntax.
        Example:
        ```[[TiddlerName]]```
        Clicking on the link will open the referenced tiddler.

    - name: URL Parameters
      description: >
        Directly access specific tiddlers by adding the tiddler name to the URL.
        Example: If your TiddlyWiki is hosted at `example.com/tiddlywiki.html`, you can open the tiddler named "MyTiddler" by navigating to:
        ```example.com/tiddlywiki.html#MyTiddler```

    - name: Tiddler Fields
      description: >
        Some tiddlers can be opened automatically based on their fields. For example, you can set a field to trigger certain actions when the tiddler is accessed.

    - name: Macros and Custom Buttons
      description: >
        Create macros or custom buttons that open specific tiddlers. For example, define a macro in your TiddlyWiki to open a tiddler when a button is clicked:
        ```javascript
        \define openTiddlerMacro(tiddlerName)
        <$button set="$:/temp/tiddler" setTo=<<tiddlerName>>>
          Open <<tiddlerName>>
        </$button>
        \end
        ```

Search and Customize Sidebar

<!-- Step 1: Check if the tiddler "$:/core/ui/PageTemplate" exists -->
<!-- Use a conditional SSI statement to mimic the tiddler existence check -->
<!--#if expr="tiddler_exists('$:/core/ui/PageTemplate')" -->
   
   <!-- Step 2: Fetch the tiddler content -->
   <!-- Simulate retrieving tiddler content -->
   <!--#set var="tiddler_content" value="get_tiddler_content('$:/core/ui/PageTemplate')" -->
   
   <!-- Step 3: Search for the sidebar widget "$:/core/ui/SideBar" -->
   <!--#if expr="strpos('$tiddler_content', '<<$:/core/ui/SideBar>>') > 0" -->
       
       <!-- Step 4: Remove or comment out the sidebar -->
       <!--#set var="tiddler_content" value="replace('$tiddler_content', '<<$:/core/ui/SideBar>>', '--<<$:/core/ui/SideBar>>')" -->
       <!--#echo var="Sidebar has been disabled." -->

       <!-- Update the modified tiddler content -->
       <!--#exec cmd="update_tiddler('$:/core/ui/PageTemplate', '$tiddler_content')" -->
   
   <!-- If the sidebar reference is not found -->
   <!--#else -->
       <!--#echo var="Sidebar reference not found. No changes made." -->
   <!--#endif -->

<!-- If the tiddler does not exist -->
<!--#else -->
   <!--#echo var="Tiddler '$:/core/ui/PageTemplate' does not exist." -->
<!--#endif -->

Search and Customize Searchbar

   <!-- Step 4: Remove or comment out the search field -->
   <!--#set var="tiddler_content" value="replace('$tiddler_content', '<<$:/core/ui/ControlPanelSearch>>', '--<<$:/core/ui/ControlPanelSearch>>')" -->
   <!--#echo var="Search field has been disabled." -->

   <!-- Update the modified tiddler content -->
   <!--#exec cmd="update_tiddler('$:/core/ui/PageTemplate', '$tiddler_content')" -->
   <!--#echo var="Search field reference not found. No changes made." -->

References

Code

Customization

customMediaType:
  title: "Custom Media Type"
  type: "application/vnd.tiddlywiki"

customMediaTypeTemplate:
  content: |
    <div class="custom-media-type">
      <h1>{{!!title}}</h1>
      <div class="media-content">
        {{!!media}}
      </div>
    </div>

storyTiddlerTemplate:
  cascadeRule: "[all[is[type[CustomMediaType]]]then[CustomMediaTypeTemplate]]"

customMediaTypeStyles:
  content: |
    .custom-media-type {
      border: 1px solid #ccc;
      padding: 10px;
      margin: 10px;
    }
    .custom-media-type .media-content {
      display: flex;
      align-items: center;
    }
    .custom-media-type .media-content img {
      max-width: 100%;
    }

References

mediawiki_successful_sites:
  wikia:
    description: "A platform for fan communities to create and share content about their favorite topics, including TV shows, movies, games, and more."
    urls:
      - "https://www.fandom.com/"

  lyricwiki:
    description: "A wiki-based lyrics database where users can contribute and edit song lyrics."
    urls:
      - "https://lyrics.fandom.com/"

  openwetware:
    description: "A wiki for the biological sciences community, used for sharing research, lab notebooks, and resources."
    urls:
      - "https://www.openwetware.org/"

  memory_alpha:
    description: "A wiki for fans of the Star Trek franchise, containing detailed information about the series, characters, and episodes."
    urls:
      - "https://memory-alpha.fandom.com/"

  wookieepedia:
    description: "A comprehensive wiki for Star Wars fans, featuring detailed information about the universe, characters, and events."
    urls:
      - "https://starwars.fandom.com/wiki/Main_Page"

  citizendium:
    description: "A wiki-based project aimed at creating a reliable, free, and open encyclopedia."
    urls:
      - "https://en.citizendium.org/"

  tv_tropes:
    description: "A wiki that catalogs and discusses various tropes found in media, including TV shows, movies, books, and more."
    urls:
      - "https://tvtropes.org/"

Cookie Tiddler

\define readCookie(cookieName)
<!-- For more information on <$macrocall>, visit: https://tiddlywiki.com/#Macro%20calls -->
<$macrocall $name=readCookie cookieName="yourCookieName"/>

<!-- For more information on <$button>, visit: https://tiddlywiki.com/#ButtonWidget -->
<$button>
  <$action-js>
    console.log(document.cookie);
    var cookieValue = "; " + document.cookie;
    var parts = cookieValue.split("; " + cookieName + "=");
    if (parts.length == 2) alert(parts.pop().split(";").shift());
  </$action-js>
  Read Cookie
</$button>
\end

Static Site External JavaScript DevOps Process

Inject JavaScript into Static TiddlyWiki Output

This walkthrough shows how to inject a custom JavaScript file into static .html pages during command-line rendering in TiddlyWiki, using a custom HTML template.


1. Template Tiddler (injects the script)

title: $:/templates/staticPageWithScript
type: text/html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title><$view field="title"/></title>
</head>
<body>
  <div class="content">
    <$transclude/>
  </div>
  <script src="custom.js"></script>
</body>
</html>

2. JavaScript Tiddler (your custom logic)

title: custom.js
type: application/javascript

console.log("Custom JavaScript loaded.");

3. Command-Line Renders

Render the HTML pages using the script-injecting template:

tiddlywiki wiki_folder \
  --load plugins/tiddlywiki/tiddlyweb \
  --load plugins/tiddlywiki/filesystem \
  --output output_folder \
  --render '[tag[static]]' \
           '[encodeuricomponent[]addsuffix[.html]]' \
           'text/html' \
           '$:/templates/staticPageWithScript'

Then render the JavaScript file itself:

tiddlywiki wiki_folder \
  --output output_folder \
  --render 'custom.js' 'custom.js' 'application/javascript'

Result

  • Your .html files will be wrapped with the injected script reference.
  • custom.js will be included alongside them in the output folder.

Personalization

  • Use the Tiddler Index: Browse all tiddlers from the "Open..." option in the "More" dropdown menu. More Menu Documentation
  • Leverage Tags: Organize tiddlers using tags and access them through the tag list in the sidebar. Tags Documentation
  • Create a Table of Contents: Build a tiddler with a list of links to other tiddlers for quick access. Links Documentation
  • Add Custom Buttons or Links: Create buttons or links in the sidebar or main toolbar to access frequently used tiddlers. Buttons Documentation
  • Use the Command Palette: Use keyboard shortcuts (Ctrl+Shift+P or Cmd+Shift+P) to navigate and interact with the wiki. Command Palette Documentation
  • Enable Custom Queries: Add input fields or filters to query and display tiddlers based on tags or other criteria. Filters Documentation
  • Maintain a Bookmark System: Create a personal tiddler containing links to frequently accessed tiddlers for easy reference. Hyperlinks Documentation

Table of Contents

PouchDB Integration

            BEFORE
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚   Tiddly    β”‚
   β”‚   Wiki      β”‚
   β”‚  Core Store β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β–²
         β”‚
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚   Tiddler   β”‚
   β”‚  (Edit/Save)β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             AFTER
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚   Tiddly    │◄────►│   PouchDB   β”‚
   β”‚   Wiki      β”‚      β”‚   Database  β”‚
   β”‚  Core Store β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β–²
         β”‚
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚   Tiddler   β”‚
   β”‚  (Edit/Save)β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Privacy

Structure

⚠️ **GitHub.com Fallback** ⚠️