Embedding Macros in [[ ]] to use for links to other tiddlers

96 views
Skip to first unread message

Ben

unread,
Nov 28, 2007, 1:04:29 AM11/28/07
to TiddlyWiki
Hello,

I want to add a macro inside the double brackets used to create links
to other tiddlers. For example: [[todays meeting: <<today "YYYY/MM/
DD">>]] I want to show up as "todays meeting: 2007/11/28" and it would
be a link to another tiddler with the same name. Right now it shows
up as "todays meeting: <<today "YYYY/MM/DD">>."

It seems to me like the today macro is executed after the creation of
the link to another tiddler in the html code. Does anyone have an
idea how I can pull this off?

Thanks, -Ben

Eric Shulman

unread,
Nov 28, 2007, 2:46:41 AM11/28/07
to TiddlyWiki
Macros do NOT generate text output that is then "glued" into the
surrounding source before final rendering. Instead, each macro is
responsible for actually rendering the browser DOM elements to display
it's own output. Thus, you cannot insert the output from a macro into
the *source* definition for a TiddlyLink because there simply is no
text output to use! Sorry.

As far as your specific question, perhaps you could use:

<<newJournal "today's meeting: YYYY/MM/DD" label:"today's meeting:
YYYY/MM/DD">>

HTH,
-e
Eric Shulman
TiddlyTools / ELS Design Studios

Jack

unread,
Nov 28, 2007, 4:16:01 AM11/28/07
to TiddlyWiki
Grab the WriteMacro (http://jackparke.googlepages.com/
jtw.html#WriteMacro) and do something like this:
<<write {{'[[todays meeting:' + (new Date()).formatString('YYYY/MM/
DD') + ']]'}}>>

Ken Girard

unread,
Nov 28, 2007, 9:01:04 AM11/28/07
to TiddlyWiki
You could use <<newJournal title:"todays meeting: YYYY/0MM/0DD">>

Ken Girard

Coby

unread,
Nov 28, 2007, 4:48:39 PM11/28/07
to TiddlyWiki
This is something I think is overlooked. There are some things a
macro can do that a PrettyLink cannot, and vice versa. For example,
the recent upgrades to <<tiddler>> to incorporate non-TW content.

As far as I know, you cannot pass the URL of a file or site to a
PrettyLink and have it open in an iframe.

(The difference between [[ ]] and << >> being that one opens on click
and the other on load. All basic TW functionality should do either.)

This (setting links to open in tiddlers) should actually be a core
default (with option to override). I detest links opening in a
separate window/tab. It breaks the Fourth Wall (Don't look it up.
That means the imaginary barrier between an actor onstage and the
audience).

I know, Saq said that the coolness of TW is not MCM but education, but
still. I use TW to manage stuff. I want to feel like I am managing
it within the environment. So I can do Tiddly stuff to the data.

So, yeah, not being able to use a macro as the source of a link is a
problem. I don't know how many times I have been frustrated by not
being able to do this thing that is so easy to visualize doing.

Couldn't you do it by going:
[[MyPretty|<iframe src=file:///mypath/mylink.ext display=0 etc></>]]?
But that's a lot to remember.

Or could you pass a parameter to a pre-defined tiddler, like:

::WorkingTiddler
[[MyPretty|ViewTiddler::file:///mypath/mylink.ext]]

::ViewTiddler
<iframe src=param1 etc.></>

Or specify (load) a JavaScript variable in the link to the tiddler,
which then would accept the variable as src=?

::WorkingTiddler
[[MyPretty|OpenLink((var MyVar))]]

::OpenLink
<<newTiddler text="<iframe src=$MyVar></iframe>">>

Plus of course you would want the viewing tiddler to open as many
instances of itself as necessary, if that is even possible...

Maybe there is something basic here. We want a macro to act like a
link sometimes, and a link to act like a macro when we need it to.
One has parameters, the other dynamic control. But the basic spirit
of TW wants to run right over that. We want our choices to have a
steering wheel. In general. But there is something fundamental about
macros and about links that makes that perplexingly difficult.

Now, if you are working in pure JavaScript or, I think, HTML, there is
no problem. But TW is an extra layer of code (defined macros) over
top of both, and that has its little quirks...

See, I can visualize a way to do it. I will leave it to you guys that
actually know something to see if it can be done.

But, like I said, this (cross-training of macros and links) is
something I run into often. I'd prefer, if possible, to see it in the
core as simple notation, rather than as a more complex plugin/macro
where you have to type out some long complex specification every time
you want to use it.

Thanks,

Coby

One final thought: Let's check our paradigm. In my uneducated
opinion, maybe the problem is not how macros are rendered (that is
more or less a given), but with how the TW-unique lookahead syntax
defines the handling of [[ ]]. Maybe we are thinking outside the
wrong box. It's not macros that need fixing, it's links.

Though if you could create a macro that:
a) had a label
b) used an onclick handler
c) opened a new tiddler displaying the link contents

that might work...

But then if you were to create such an animal, we would just be at you
again, begging for a way to dynamically specify the links...

How weird. We want browser-like functionality inside TW inside a
browser.

On the other hand, how useful is a micro-content manager that can only
manage a few kinds of content, in a few ways?

Eric Shulman

unread,
Nov 28, 2007, 6:31:32 PM11/28/07
to TiddlyWiki
> Though if you could create a macro that:
> a) had a label
> b) used an onclick handler
> c) opened a new tiddler displaying the link contents
> that might work...

http://www.TiddlyTools.com/#InlineJavascriptPlugin
lets you quickly create "onclick" handlers, for example:

<script label="text to click goes here" title="tooltip">
displayTiddler(null,"MyTitle");
</script>

> begging for a way to dynamically specify the links...

For your specific issue (clicking an external link and viewing the
result in an IFRAME), you might try one of these scripts that uses the
extra "with:" parameters of the <<tiddler>> macro to "dynamically
specify the links":

http://www.TiddlyTools.com/#LinkFrame
usage: <<tiddler LinkFrame with: label url>>

and/or

http://www.TiddlyTools.com/#SliderFrame
usage: <<tiddler SliderFrame with: label url width height frameID>>

> How weird. We want browser-like functionality inside TW inside a
> browser.

Try this one:
http://www.TiddlyTools.com/#MiniBrowserPlugin

> On the other hand, how useful is a micro-content manager that can only manage a few kinds of content, in a few ways?

http://www.TiddlyTools.com/#BookmarkPackage
Uses custom BookmarkViewTemplate and BookmarkEditTemplate to create
tiddlers that define "bookmarks" to external URLs (using tiddler
slices) so that clicking a link to [[SomeBookmark]] opens and
automagically renders that tiddler's URL into an embedded IFRAME.

Eric Shulman

unread,
Nov 29, 2007, 10:45:30 AM11/29/07
to TiddlyWiki
> As far as I know, you cannot pass the URL of a file or site to a
> PrettyLink and have it open in an iframe.

You can now! :-) I've just written:
http://www.TiddlyTools.com/#FramedLinksPlugin

When enabled, this plugin causes clicks on external links to be
rendered into inline frames ("IFRAME") instead of opening them in new
browser tabs/windows. Just place an external link into your tiddler
content using standard TiddlyWiki syntax. When you click that link,
the IFRAME will be created immediately following the external link.
Clicking on the link again removes the IFRAME.

You can enable/disable this behavior via an option checkbox (<<option
chkFramedLinks>>. Alternatively, you can hold down a modifier key
(shift, control, or alt) while clicking a specific link to //
temporarily// bypass the plugin-enhanced IFRAME handling and use the
standard link handling behavior for that link.

enjoy,

Dave Parker

unread,
Nov 29, 2007, 11:56:18 AM11/29/07
to TiddlyWiki
Hi Eric, just a little troubleshooting -

I see this in your plugin:

if (config.options.txtFrameWidth==undefined)
config.options.txtFrameWidth="100%";

In my TW I'm using I have skinnier columns, but for some things (like
iframes) I usually set the width to 150%. When I change the second
line above there to 150%, the width doesn't change. So I thought,
maybe it only does it if its not already defined (as per the line
above), do I just deleted that line - but that just caused an error.

any suggestions?

DP

Eric Shulman

unread,
Nov 29, 2007, 12:40:15 PM11/29/07
to TiddlyWiki
> if (config.options.txtFrameWidth==undefined)
> config.options.txtFrameWidth="100%";

> iframes) I usually set the width to 150%. When I change the second
> line above there to 150%, the width doesn't change. So I thought,

If you changed the width via the <<option txtFrameWidth>> input field,
then it created a local cookie. That value will take precedence over
the hard-coded default. Clear your cookies and try again...

... and, you should also get the updated plugin (v1.0.1), which
includes fixes in handling for height and width to help maximize the
space given to an IFRAME

http://www.TiddlyTools.com/#FramedLinksPlugin

enjoy,
-e

Coby

unread,
Nov 30, 2007, 4:44:42 PM11/30/07
to TiddlyWiki
Rock on! Thank you!

This will let me have the "look and feel" I'm looking and feeling for.

Coby

wolfgang

unread,
Dec 25, 2007, 10:31:07 AM12/25/07
to TiddlyWiki
Hi Eric,

> Macros do NOT generate text output that is then "glued" into the
> surrounding source before final rendering. Instead, each macro is
> responsible for actually rendering the browser DOM elements to display
> it's own output. Thus, you cannot insert the output from a macro into
> the *source* definition for a TiddlyLink because there simply is no
> text output to use! Sorry.

Then I don't understand why PopupMacro seems to be able to do exactly
that:

<<popup 'Inline Custom Menu' [[Custom Menu *MainMenu ----
<<forEachTiddler where 'tiddler.tags.contains("systemConfig")']]$))]]
>>

What is it that I misunderstand here??

Regards,

W.

http://tw.lewcid.org/#PopupMacro

Eric Shulman

unread,
Dec 25, 2007, 11:55:36 AM12/25/07
to TiddlyWiki
> Then I don't understand why PopupMacro seems to be able to do exactly
> that:
>
> <<popup 'Inline Custom Menu' [[Custom Menu *MainMenu ----
> <<forEachTiddler where 'tiddler.tags.contains("systemConfig")']]$))]]
> What is it that I misunderstand here??

TiddlyLinks have different syntax from macros. The parts of the link
definition do NOT get wikified, so there is NO opportunity for macro
processing to be invoked.

In contrast, macros have "handler" functions that can process and
*convert* macro parameters using whatever internal functions they
need. This allows macros to perform all sorts of 'fixup' handling.
For example, in <<forEachTiddler>>, Saq has to tweak the macro
parameter using "$))" in place of ">>" so that the embedded macro
doesn't break the containing macro's syntax.

-e

Eric Shulman

unread,
Dec 25, 2007, 1:11:27 PM12/25/07
to TiddlyWiki
> For example, in <<forEachTiddler>>, Saq has to tweak the macro

errata:

<<forEachTiddler>> is by Udo Borkowski, not Saq Imtiaz

-e

wolfgang

unread,
Dec 25, 2007, 1:17:11 PM12/25/07
to TiddlyWiki
> I want to add a macro inside the double brackets used to create links
> to other tiddlers.
>

> TiddlyLinks have different syntax from macros. The parts of the link
> definition do NOT get wikified, so there is NO opportunity for macro
> processing to be invoked.
>
> In contrast, macros have "handler" functions that can process and
> *convert* macro parameters using whatever internal functions they
> need. This allows macros to perform all sorts of 'fixup' handling.
> For example, in <<forEachTiddler>>, Saq has to tweak the macro
> parameter using "$))" in place of ">>" so that the embedded macro
> doesn't break the containing macro's syntax.

Now I think I'm even more confused. 8-p

For example: If I use the popup macro, it is possible to add the
external tiddler macro inside translated double brackets - and the
macro gets invoked with PopupPlugin's small translating and additional
code:

<<popup view [[<<tiddler "js/$2"$))]]>>

So by extracting Saq's handling function - guess it would be easy to
add this function as a general Plugin for having macros invoked within
WikiLinks without the PopupPlugin.

W.

Eric Shulman

unread,
Dec 25, 2007, 1:17:32 PM12/25/07
to TiddlyWiki
> In contrast, macros have "handler" functions that can process and
> *convert* macro parameters using whatever internal functions they
> need. This allows macros to perform all sorts of 'fixup' handling.

In this particular case, the <<popup>> macro has an even more direct
purpose: to create a popup container and then "wikify" into it. That
is the real reason that "popup" macro seems to be able to accept
another macro as a parameter value. Once it creates the container,
<<popup> does not actually parse the parameter itself, but merely
hands it off to the core's wikify() function for actual rendering.

My original response still stands:
** macros do not return text... they render DOM elements... **
so a strategy that seeks to 'glue' together macro output and THEN
parse/render it as wiki-syntax simply will not work.

-e

Eric Shulman

unread,
Dec 25, 2007, 2:23:55 PM12/25/07
to TiddlyWiki, ho...@unamesa.org, elsd...@gmail.com
> > I want to add a macro inside the double brackets used to create links
> > to other tiddlers.

> Now I think I'm even more confused. 8-p

apparently so.... But that's OK... you'll get over it... :-)

> For example: If I use the popup macro, it is possible to add the
> external tiddler macro inside translated double brackets - and the
> macro gets invoked with PopupPlugin's small translating and additional
> code:
> <<popup view [[<<tiddler "js/$2"$))]]>>
> So by extracting Saq's handling function - guess it would be easy to
> add this function as a general Plugin for having macros invoked within
> WikiLinks without the PopupPlugin.

This still does not make any sense to me... I will try saying it
again: **macros do NOT return text output, they render DOM elements
into the browser**... Suppose we *could* invoke the macro from within
the WikiLink syntax... since the macro doesn't give back TEXT, there
would be *nothing* for the WikiLink handler to create a link from!!!
What would you want it to do in that case?

Perhaps your confusion is due to the multiple uses of the [[...]]
syntax. Here's a overview of the different places that [[...]] can
occur, and how they differ:

In regular content:
[[TiddlerName]] is a TiddlyLink. The stuff inside the brackets is
NOT passed through the wikify() parser, and is expected to simply be
the title of a tiddler. The brackets are essential for creating
TiddlyLinks to non-WikiWord tiddler titles or PrettyTiddlyLinks (i.e.,
the "[[text to show|tiddler name]]" syntax)

In a macro:
Although [[...]] can be used to surround a tiddler title (e.g., one
that contains spaces) being used as a macro parameter value, their use
in a macro does not necessarily mean that the value inside the
brackets is a TiddlyLink or even a reference to a tiddler title. The
[[...]] are simply an alternative method of "quoting" a parameter
value, so it can contain spaces as well as mix of double- and/or
single-quotes, like this:
<<someMacro stuff [[It's got both kinds of "quotes" in it]]
morestuff>>

In a stylesheet:
[[TiddlerName]] inserts the content from TiddlerName into the
stylesheet
(note: in this is specific case, the core DOES 'glue' the CSS
content together before passing it on to the browser, so 'text
subtitution' strategies DO work for stylesheets. For example, [[...]]
is used by the shadow stylesheets (e.g., StyleSheetColors) to insert
values from the default ColorPalette definition (another shadow
tiddler), making it easier to change the overall color scheme without
having to edit the CSS directly, simply by editing the RGB values in
the ColorPalette tiddler instead.

In a template:
[[...]] usually means nothing. Templates use HTML <...> syntax
(plus a few non-standard, TW-parsed, extended HTML attributes, such
as: macro="..." However, one place where [[...]] is really useful in
a template is when invoking a macro via:
<span macro="someMacro stuff [[It's got 'single-quotes' in it]]
morestuff"></span>
or
<span macro='someMacro stuff [[It's got "double-quotes" in it]]
morestuff'></span>
Because the template syntax uses one set of quoting symbols (either
single- or double-quotes), the [[...]] syntax becomes essential for
surrounding parameters that contain spaces and/or quotes (but only one
kind at a time)

and, there you have it.

whew! ... I had fun explaining that... I hope it helps clear up more
confusion than it causes :-)
Reply all
Reply to author
Forward
0 new messages