Dealing with non text tiddlers in TiddlyWiki

45 views
Skip to first unread message

rakugo

unread,
Jun 10, 2010, 10:01:43 AM6/10/10
to TiddlyWikiDev
Hi,
In working on TiddlyWebWiki and TiddlySpace I think we are at the
stage where it would be good to have a good solid story for including
tiddlers with text describing a data format other than text ie. by
this I mean images, svg files, videos etc etc..

I brought this subject up in the TiddlyWeb group (See
http://groups.google.com/group/tiddlyweb/browse_thread/thread/c23bfdf5fafabfee)
and it has been suggested that tiddlers (up to a certain style) are
delivered with base64 data URI as the tiddler.text and fields
containing any extra required metadata. A tiddler type attribute would
identify what the tiddler text describes? For example the tiddler type
might be image/xml+svg and the tiddler text might be the source code,
or alternatively it might be image/png and the tiddler text might be a
data uri. Viewing an image tiddler in normal TiddlyWiki might show
gobbledygook but with the addition of a plugin/adaption of the
wikifier clicking on the tiddler would show the image it represents in
place of the text.

Does anyone see a reason why we might not want to do this and can
suggest a better way of doing this?

I'm looking for us to agree on this so that we can concentrate on
writing plugins that make use of the type to render the tiddler
correctly.

Any thoughts?
Jon

Eric Shulman

unread,
Jun 10, 2010, 8:16:03 PM6/10/10
to TiddlyWikiDev
> and it has been suggested that tiddlers (up to a certain style) are
> delivered with base64 data URI as the tiddler.text and fields
> containing any extra required metadata. A tiddler type attribute would
> identify what the tiddler text describes? For example the tiddler type
> might be image/xml+svg and the tiddler text might be the source code,
> or alternatively it might be image/png and the tiddler text might be a
> data uri. Viewing an image tiddler in normal TiddlyWiki might show
> gobbledygook but with the addition of a plugin/adaption of the
> wikifier clicking on the tiddler would show the image it represents in
> place of the text.

See:
http://www.TiddlyTools.com/#AttachFilePackage
In particular,
http://www.TiddlyTools.com/#AttachFileSample
uses native TW *section* syntax to define 3 possible sources for the
'attached' binary content:
* a local path/file reference,
* a remote URL,
* base64-encoded data

These 3 potential sources are used for multi-tiered fallback handling
by
http://www.TiddlyTools.com/#AttachFilePluginFormatters
which extends the TW pretty link and image syntax ([[text|...]] and
[img[...]], respectively) to permit use of 'attachment tiddler' titles
in place of the usual external path/file or URL reference.

The enhanced formatters first look for base64-encoded data stored in
the specified tiddler. If no encoded data is present (or you are
using IE, which doesn't support the data:// URI syntax), then the
formatter looks for a local path/file. If the file is not found (or
no local reference is defined for the attachment), then the external
URL reference is used. If the URL is not defined (or isn't a valid
address), the browser's normal 'broken image' display handling takes
over.

Note that, because attachment tiddlers use ***TW-native section
syntax***, you can easily edit it as needed by employing the standard
TW editor, without needing any custom fields at all. It also makes it
easy to embed the content of individual sections into other tiddlers
by using TW standard <<tiddler TiddlerName##sectionname>> syntax.

In addition, the section syntax is very portable: you can copy an
attachment tiddlers (and the AttachFilePluginFormatters 'runtime') to
any other TW document


In fact, once you have embedded base64-encoded image data in a
tiddler, it can be embedded directly into the document's
[[StyleSheet]] to define CSS background images, without using ANY
plugins at all!

For example, you can write:
body { background-image: url('[[MyBackground##data]]'); }
to embed the encoded data:// URI directly into the StyleSheet. Of
course, this usage simply assumes that the encoded data is present in
the attachment (and is supported by the browser) and completely
bypasses the 3-tier fallback mechanism provided by
AttachFilePluginFormatters.

In contrast, when the enhanced formatters ARE installed, then you can
omit the "##data" portion from the StyleSheet reference and just refer
to the attachment tiddler itself, and allow the plugin's fallback
handling to do the rest:
body { background-image: url('[[MyBackground]]'); }

Another advantage of the 3-tier fallback approach is that it allows
for efficient distribution of documents with external images:
* send a document, with embedded data, for totally self-contained
use
* send a much smaller document using file-based attachments, along
with the accompanying set of image files for offline/local viewing
* or send the document but *not* the image files, and allow the
attachment formatters to use a remote fallback URL where you have
posted the images online.

enjoy,
-e
Eric Shulman
TiddlyTools / ELS Design Studios

chris...@gmail.com

unread,
Jun 25, 2010, 6:50:36 AM6/25/10
to TiddlyWikiDev
On Thu, 10 Jun 2010, Eric Shulman wrote:

> Note that, because attachment tiddlers use ***TW-native section
> syntax***, you can easily edit it as needed by employing the standard
> TW editor, without needing any custom fields at all. It also makes it
> easy to embed the content of individual sections into other tiddlers
> by using TW standard <<tiddler TiddlerName##sectionname>> syntax.

While this is good for TiddlyWiki, especially those which are file:///
based, it is less good for server-side storage systems that store
individual tiddlers (rather than whole wikis). TiddlyWeb being the
example that I know about.

In TiddlyWeb a tiddler is stored a combination of headers (attributes
and fields) and a body. That body is usually wikitext, but if the
'type' attribute is set, you can put pretty much anything in the body.
How it is stored depends on the storage system, the default text store
encodes MIME types that start with something other that 'text/' in
base64 encoded form.

When such a tiddler is retrieved from the server it is packaged up
according to its mime-type and the mime-type of the Accept header
provided in the HTTP request. If you ask for JSON you get a JSON
dictionary with the text attribute as the base64 encoded binary
content. This can then be injected into a TiddlyWiki as required.

What I would prefer to see for binary tiddlers is:

* tiddler.text is either a data uri containing encoded binary stuff or
remote URI which has the stuff
* tiddler.fields[something] contains metadata about the binary stuff
including amongst other thing an indicator that this is a binary tiddler
* Core or CoreTweaked support for binary tiddler awareness in
TiddlyWiki, such that refresh or edit of a binary tiddler enters a
binary tiddler code path.

-=-=-
The above is not necessary, though, if a structured binary tiddler
with sections is preferred. For TiddlyWeb, if the format is specced
out, we could include support for it in the tiddlywiki serializaiton
in TiddlyWebWiki.

--
Chris Dent http://burningchrome.com/~cdent/
[...]

Eric Shulman

unread,
Jun 25, 2010, 8:08:20 AM6/25/10
to TiddlyWikiDev
> While this is good for TiddlyWiki, especially those which are file:///
> based, it is less good for server-side storage systems that store
> individual tiddlers (rather than whole wikis).

I don't agree. The design that I have *already implemented* and which
is *widely used* in the community does NOT rely on any file-level
granularity. Just as with any other tiddler, each attachment tiddler
can be independently stored (e.g., TiddlyWeb), or stored as part of a
complete file-save action (e.g., TiddlySpot).

> * tiddler.text is either a data uri containing encoded binary stuff or
>    remote URI which has the stuff
> * tiddler.fields[something] contains metadata about the binary stuff
>    including amongst other thing an indicator that this is a binary tiddler
> * Core or CoreTweaked support for binary tiddler awareness in
>    TiddlyWiki, such that refresh or edit of a binary tiddler enters a
>    binary tiddler code path.

Except for your insistence on using custom tiddler fields, the
underlying design you propose is quite similar to what I have already
done. Instead of using custom fields to hold the base64 text-encoded
data and related meta-data, I used standard TW section syntax, plus a
single 'attachment' tag value to indicate the tiddler's "type". The
plugin adds 'binary tiddler awareness' for the core [img[...]] and
[[text|...]] syntax, so that a simple reference to an attachment
tiddler may be used in place of an external URL.

The plugin also provides two public functions, 'isAttachment()' and
'getAttachment()' that make it very easy for other plugins to directly
access the data stored in the attachment. Examples include:
ImageSizePlugin, ImagePathPlugin, PlayerPlugin, TiddlyPodPlugin,
SetIconPlugin, and several others.

As a general rule for TiddlyWiki, I *strongly* prefer NOT to obscure
the data in tiddlers by hiding them in custom fields unless there is a
*very* compelling reason to do so. Otherwise, it just adds
complexity, reduces flexibility, and blocks access to the information
from the document's owner.

In particular, using custom fields makes the information less portable
between documents, as it *requires* non-standard edit-mode handling
(to display/modify those fields), or at least non-standard tiddler-
saving actions (to re-interpret user input and add custom fields). In
contrast, tiddler sections are modified using the standard TW
interface, just like any other tiddler, and do not require any special
handling at all to be stored or copied, and individual tiddlers (or
sets of tiddlers) can be easily imported/exported between documents
without needing to support any non-standard editing/saving for those
tiddlers.

In addition, as previously noted, even without installing the
AttachFilePluginFormatters runtime support, you can still access and
even *render* any base64-encoded image data by reference to the
attachment's [[TiddlerName##data]] slice value, using slice-embedding
features, such as the <<tiddler>> macro.

For example, you could write a simple tiddler, [[ShowImage]],
containing:
/%
!out
[img[$1]]
!end
%/<<tiddler ShowImage##out
with: {{store.getTiddlerText("$1##data")}}>>

which invoke by writing:
<<tiddler ShowImage with: SomeAttachmentTitle>>

In summary: I don't see *any* net advantage to hiding attachment data
in custom fields. It seems contrary to the 'open information' nature
of TiddlyWiki, and makes it harder to share that information across
the entire TiddlyVerse, because it would be locked in to TiddlyWeb's
server-side representation, which will force TW authors to use custom
fields and non-standard editing, even for documents that are NOT
intended for TiddlyWeb storage.

-e

chris...@gmail.com

unread,
Jun 25, 2010, 8:23:21 AM6/25/10
to TiddlyWikiDev
On Fri, 25 Jun 2010, Eric Shulman wrote:

>> While this is good for TiddlyWiki, especially those which are file:///
>> based, it is less good for server-side storage systems that store
>> individual tiddlers (rather than whole wikis).
>
> I don't agree. The design that I have *already implemented* and which
> is *widely used* in the community does NOT rely on any file-level
> granularity. Just as with any other tiddler, each attachment tiddler
> can be independently stored (e.g., TiddlyWeb), or stored as part of a
> complete file-save action (e.g., TiddlySpot).

What I meant was not an attachment system that relies on file-level
granularity, but rather that using your style of storing "binary"
tiddlers is fundamentally better for TiddlyWiki's which store to
local disk (i.e are using in the browser at file:/// URIs) but
fundamentally complexifying for server-sides which store (and
provide in multiple serializations) tiddlers as single units.

There's more to respond to in the rest of the thread, but I'm hoping
other's will get involved before I say more. I just wanted to clear
up the above.

FND

unread,
Jun 25, 2010, 9:05:26 AM6/25/10
to tiddly...@googlegroups.com
> In summary: I don't see *any* net advantage to hiding attachment data
> in custom fields. It seems contrary to the 'open information' nature
> of TiddlyWiki, and makes it harder to share that information across
> the entire TiddlyVerse

I understand where you're coming from, and coming from a TiddlyWiki
background myself I can relate to and agree with much you've said.

However, the problem I see here is being tied to the TiddlyWiki
universe. Your approach - leveraging sections and slices - requires
parsing of the tiddler body, and thus a certain awareness of its
structure. This is problematic for a generic system like TiddlyWeb,
which is designed to be content-agnostic.

I'll have to do more pondering on how we might reconcile these
requirements before making up my mind...


-- F.

Paul Downey

unread,
Jun 25, 2010, 10:47:56 AM6/25/10
to tiddly...@googlegroups.com
> I'll have to do more pondering on how we might reconcile these requirements
> before making up my mind...

In the hope of helping the requirements discussion, I've started to
put together a small space demonstrating using SVG, and other "binary"
tiddlers using a simple image "chili":

http://chili.tiddlyspace.com/

It very possibly contains errors, and misunderstandings and I'm happy
to add others as members to help explore this "space".

--
Paul (psd)
http://blog.whatfettle.com

chris...@gmail.com

unread,
Jul 1, 2010, 5:49:36 AM7/1/10
to TiddlyWikiDev
On Jun 25, 2:05 pm, FND <F...@gmx.net> wrote:
> However, the problem I see here is being tied to the TiddlyWiki
> universe. Your approach - leveraging sections and slices - requires
> parsing of the tiddler body, and thus a certain awareness of its
> structure. This is problematic for a generic system like TiddlyWeb,
> which is designed to be content-agnostic.

This isn't necessarily that much of a problem. If the content needs to
appear in a particular form in the TiddlyWiki, then the server-side
just needs to make sure that it properly processes to that form when
generating the TiddlyWiki. The storage system can continue to do
whatever it likes. Serializing to a particular form on the server is
not too terribly complicated.

What becomes complicated is making sure that the TiddlyWiki does the
right form of PUT to save stuff back to the server. That complexity
can be held in the client (where it ought to be for sake of
scalability and tweakability).

So really, it is a matter, as we've been saying, of agreement on some
format, any format really, that is satisfactory for the various client
side use cases and then documenting it so server-sides can serialize
to it.

rakugo

unread,
Jul 14, 2010, 4:07:35 AM7/14/10
to TiddlyWikiDev
I see merit in both approaches, however at the risk of opening a
tiddler slices vs fields argument, semantically I have an issue with
the slice approach.

To me the word text in terms of a tiddler means content of that
tiddler.
In the case of a plugin, the text is the content of that plugin - the
javascript - the source code.

In the case of an image, I would therefore expect the content of that
tiddler to be the data representing that image.
A data uri, as in the example contains the mime-type, so the type
field seems a bit redundant as a result (as you can extract it from
the data).

However, what I would like is an easy *quick* way in my plugins to
work out whether a tiddler should be treated normally, or specially. I
can get the tiddler slice for type in your method, however I'm
concerned that if I had a several megabytes file (leading to extremely
long tiddler text), the get tiddler slice method might be slow. Using
a field for this, would grant quick access to plugins to this
important data, and the fact that it is not editable via standard
tiddlywiki could be a good thing - I shouldn't need to change the type
if plugins are doing it for me. If you can prove me wrong on this
concern, that would be a relief.

The url/path fallback also concerns me slightly.
By storing data in this way, theoretically I could change the url of
the image to point to something else. Then the data in the data
section corresponds to something completely different to the url.
Likewise I could incorrectly set a type to be image/png when actually
the data uri says it is image/jpeg. Doesn't this undermine the data
integrity?

I however see use in the notes markup - if I have a base64 image or
some svg, it would be good to be able to have some text fallback to
describe the drawing (which could also be used as an alternative text
when either can not be rendered), so that when I click edit without
any plugins I have some context to what I am viewing.

I've not been very helpful here... sorry :) I'm still on the fence
observing the different possibilities.
Jon

chris...@gmail.com

unread,
Jul 22, 2010, 5:22:59 AM7/22/10
to TiddlyWikiDev

NOTE: The below applies to TiddlyWikis generated by TiddlyWeb, not
TiddlyWiki in general.

On Wed, 14 Jul 2010, rakugo wrote:

> In the case of an image, I would therefore expect the content of that
> tiddler to be the data representing that image.
> A data uri, as in the example contains the mime-type, so the type
> field seems a bit redundant as a result (as you can extract it from
> the data).

In the latest release of TiddlyWebWiki, the above is effectively what
we have done. The choice to do it that way basically comes down to one
thing: it's simple and predictable.

Tiddlers are packaged in the generated tiddlywiki file in one of three
ways:

* they are a "normal" tiddler, meaning they have no special
content-type and are packaged as you would expect: wikitext
inside the div.

* they are a pseudo-binary tiddler: The text inside the div is a
textual representation of some non wikitext format, such as
image/svg+xml. There is a server.content-type attribute which has
the relevant mime type of the content.

* they are a binary tiddler: The text inside the div is a base64
encoded representation of a non-textual thing, such as image/png.
There is a server.content-type attribute which has the relevant mime
type of the content.

server.content-type is being used for the time being until there is
some consensus on where the type information should go.

FND created a plugin called BinaryTiddlersPlugin which does the bare
minimum basics of properly rendering base64 stuff into either img or
anchor tags with data uris. Beyond the basics is the realm of
additional plugins.

You'll note some caveats with all this:

* _Any_ binary content is sent out with the TiddlyWiki. This means
that if for some reason there is a 1GB movie tiddler on the server,
and you ask for it in a TiddlyWiki, you'll get a giant tiddler in
your TiddlyWiki.

* For the time being data:uris are being used. Some browsers don't
support them. Some browsers limit the amount of data that can be in
them.

* Because of changes in TiddlyWeb with how "binary" and
"pseudo-binary" are distinguished on the server, some tiddlers may
be base64 when they should be text.

We'll let this stuff ride for a while and adjust as feedback happens.

I can predict one thing that might need to happen is that sending the
binary content may be a configuration option. If it is not set, then
do links as before.

Eric Shulman

unread,
Jul 22, 2010, 12:41:59 PM7/22/10
to TiddlyWikiDev
> FND created a plugin called BinaryTiddlersPlugin which does the bare
> minimum basics of properly rendering base64 stuff into either img or
> anchor tags with data uris. Beyond the basics is the realm of
> additional plugins.

Note: AttachFilePluginFormatters, which is used in many existing TW
documents, already extends the TW image and link syntax to handle
references to tiddlers containing base64-encoded binary.

In light the widespread use of TiddlyTools' AttachFilePlugin, it's
important to ensure that TiddlyWeb's BinaryTiddlersPlugin can properly
co-exist with my current plugin, by hijacking the formatters, rather
than overwriting them. Otherwise, if someone is using TiddlyWeb, they
will be unable to use any AttachFilePlugin-generated binary
attachments that already exist in their documents, and will also be
unable to share and use AttachFilePlugin-generated binary attachments
with others who are not using a TiddlyWeb-hosted document.

thanks,
-e

FND

unread,
Jul 23, 2010, 12:06:13 PM7/23/10
to tiddly...@googlegroups.com
> it's important to ensure that TiddlyWeb's BinaryTiddlersPlugin can properly
> co-exist with my current plugin, by hijacking the formatters, rather
> than overwriting them.

BinaryTiddlersPlugin does not override any formatters, but rather hooks
into config.macros.view.views.wikified - plus it is only activated if
the respective tiddler has a "server.content-type" custom field.
So both plugins should be able to co-exist just fine - is this not
actually the case?


-- F.

Eric Shulman

unread,
Jul 23, 2010, 6:03:16 PM7/23/10
to TiddlyWikiDev
That sounds like it won't conflict, so I *think* it's OK from my
standpoint.

I don't know of any *actual* conflicts between the two plugins... it's
just that there are so many use-case combinations and permutations in
the TiddlyVerse, that when any two plugins even *seem* to address the
same functional areas, a 'flag' goes up in my mind to make sure that
the compatibility issues are being considered carefully.

When I'm not quite as busy (when is that? :-), I'll definitely take a
closer look at how you've implemented things... it sounds intriguing.

-e

>
> -- F.

FND

unread,
Jul 24, 2010, 1:35:13 PM7/24/10
to tiddly...@googlegroups.com
> I don't know of any *actual* conflicts between the two plugins [...]
> a 'flag' goes up in my mind to make sure that the compatibility
> issues are being considered carefully.

I'm glad you're being vigilant!

> When I'm not quite as busy (when is that? :-), I'll definitely take a
> closer look at how you've implemented things... it sounds intriguing.

I just realized we haven't posted the URL yet, so here goes:
http://svn.tiddlywiki.org/Trunk/association/plugins/BinaryTiddlersPlugin.js

As Chris has said, it's tiny and intentionally basic.


-- F.

Reply all
Reply to author
Forward
0 new messages