It’s is good to know that, despite the critical approach to TW, Riz is committed to maintain Timimi, as it’s one of the easiest path to storing your TW locally and the route we follow here after having a public wiki in TiddlyHost.
Regarding Riz’s criticisms I don’t share the starting premise: the idea of wanting to have single TW with everything on it as an stressing point in my use cases. And I found splitting my wikis by topic and audience a powerful knowledge management mechanism (personal private/public, our table role playing group, the data activism grassroots community, my general classes, wiki/hipertext learning, among others).
That being said, I share some of the criticisms. I share the one regarding the default UI feeling kind of old, but that have been addressed in several theme and ui tweaking discussions, so I will address other two.
NodeJS seems overkilling when HTML files are not enough
There are lighter self containd alternatives like TW5-Server. But, part of the JS culture creates this maximalist approaches (if plain JS is not enough, go with the overcomplex framework of the week, headless full browser Electron or huge NodeJS and its dependencies). And while each culture has its caveats and advantages, I think that, as a TW community, we should explore and make more visible more minimalist, non JS nor full blown solutions. With TiddlyWikiPharo we are trying that approach, and because we use Nim for some external optimizations, maybe we’ll use TW5-Server in the future.
Operators/filters knowledge seems too specific and difficult to recontextualize elsewhere
I like the way TW created a continuum that blurs the distinction between user and developer, instead of those high barriers being put in other wiki software, where the jump between being a “content creator” and a “functionality creator” is pretty big. In contrast, in TW you go from formating wiki text, to macros, to filters and extra operators in a mostly pretty fluent way. I have seen that with some of my learners in my classes and workshops.
That being said, the more complex the filters and customizations go, the more you need the particular ways of TW, knowing that they will not be transferable elsewhere which, at least in my case, make me practice them in pretty constrain settings and do most of my data manipulation in Pharo (as shown in the data stories about migrations from Hugo and from Wordpress to TW).
What I would like is to be able to extend TW in several languages, once its data has been exposed in JSON. This is the approach we use in TiddlyWikiPharo by parsing (with Nim optimizations) the HTML file, looking for the JSON tiddlers. But something easier should be provided by default, kind of the /tiddlers.json
address provided by TiddlyHost, if we want an easier cross-language extension mechanism that doesn’t require a full NodeJS server behind to work, but it is provided by the default HTML single file (because it already knows how to store and read itself as JSON).
Exposing the JSON storage as a easy prepackaged default will open possibilities to use TW not only from external languages and frameworks beyond JS/NodeJS (as we do with Pharo and Nim), but also from “internal” ones, which would create more extension mechanisms to traverse/blur the gap between content and functionality creators.
For example, I imagine adding a Fengari plugin included in some stand alone version of TW that makes TW extensible from Lua using some kind of Lua powered domain specific language (DSL) for tiddlers’ querying, composing, building and styling. The language can be similar to the one used in Typst “hashtag” functions but using Lua tables/functions to query and compose tiddlers. So a functionality like the one in this filter, could be expressed in an imaginary Lua DSL:
--||
all()
|> select()
|> taggedAs("member")
|> ramdomized()
|> styled("MemberTemplate")
--|
The user would loose the compactness of <$list filter="[tag[member]choose-random:all[]]">
of the initial tiddler example, in this imaginary Lua DSL (influenced by Elixir’s pipe operator). But, by using functions to compose a tiddler’s query, randomize its result and injecting that into view, s/he would gain exposure to functional programming concepts (listed below), while keeping them simple in an easy to learn language. In this way, the usage of alter filters outside TiddlyWiki is high, as it is bringing back knowledge outside of web programming (e.g. from the diverse Lua ecosystem) into TW.
For example, in the previous code, the all() |> select ()
could be replaced by selectAll()
, which would be defined in some “Lua tiddler macro” as something like:
function select(reach)
if reach == "all" then
return selectAll()
end
-- ... other selection cases follow
end
function selectAll()
return select(all())
end
And so, filters could be an example of DSLs, pipe operators and functions, function composition and a bridge to the Lua language, that would have a gentle learning curve, as we do with TW operators today, but with more reusability potential.
Of course, this is easier said than done and there is a long path ahead to follow this, including parser changes to support other languages and DSLs. But this could be easily started by improving the exposing of the JSON storage.
As a working conclusion…
While TW’s criticisms and their validity depend on the context where they arise and despite TW providing a fluent experience when is “used as intended” (and its many intended uses behind), it is easily stressed when is not: large wikis, complex theming, non JS or Node. Some of the criticisms can be addressed, kind of swiftly, by exposing TW storage internals so more languages and frameworks, avoiding the incidental current complexity and lack of recontextualization that is behind many of such criticisms.
How to traverse and open the possibilities, as a community, is still an open question, as more experimentation is needed (I’ll do my part by sharing my experiences of extending TW mostly outside of TW).
Ps: The code for the imaginary Lua TiddlyWiki DSL could also be written as the equivalent:
--||
taggedAs("member")
|> ramdomized()
|> styled("MemberTemplate")
--|
which shows that once a sound extension DSL have been implemented, economy of language and composition becomes easier… of course is even easiest in the plane of imaginary extension DSL and details are in the implementation.