Why is this conditional in config.macros.tags.handler?

32 views
Skip to first unread message

Scott Steele

unread,
Jun 23, 2011, 5:56:03 PM6/23/11
to TiddlyWiki
I've set up a plugin to exclude tags and tiddlers from tag and
reference lists only when my site is in read-only mode and only then
if the tag or tiddler is tagged with a special Editor-Only Tag, which
indicates that that tag or tiddler is strictly backstage and should
not be visible to the casual visitor.

From the visitor's standpoint, the plugin works great. It does what it
is supposed to do. However, when I am backstage myself and manually go
to a tiddler with the Editor-Only Tag, I'm getting a 'macro error' in
the tag list instead of a 'no tags' label.

Here's my plugin code:

//{{{

config.macros.tags.handler =
function(place,macroName,params,wikifier,paramString,tiddler)
{
params = paramString.parseParams("anon",null,true,false,false);
var ul = createTiddlyElement(place,"ul");
var title = getParam(params,"anon","");
if(title && store.tiddlerExists(title))
tiddler = store.getTiddler(title);
var sep = getParam(params,"sep"," ");
var lingo = config.views.wikified.tag;
var label = null;
for(var t=0; t<tiddler.tags.length; t++) {
var tag = store.getTiddler(tiddler.tags[t]);
if(!tag || !tag.tags.contains("excludeLists")) {
if(!config.options.chkHttpReadOnly || !
tag.tags.contains(config.options.txtEditorOnlyTag)) {
if(!label)
label =
createTiddlyElement(ul,"li",null,"listTitle",lingo.labelTags.format([tiddler.title]));

createTagButton(createTiddlyElement(ul,"li"),tiddler.tags[t],tiddler.title);
if(t<tiddler.tags.length-1)
createTiddlyText(ul,sep);
}
}
}
if(!label)

createTiddlyElement(ul,"li",null,"listTitle",lingo.labelNoTags.format([tiddler.title]));
};

//}}}

The only thing I did to change it from the main tags handler was to
add this conditional mid-way down:
{{{if(!config.options.chkHttpReadOnly || !
tag.tags.contains(config.options.txtEditorOnlyTag)) }}}

(I'm currently using excludeSearch as txtEditorOnlyTag since
excludeSearch does a number of viewer/editor segregation chores for me
already.)

The conditional I'm trying to understand is {{{ if(!tag || !
tag.tags.contains("excludeLists")) }}}
It comes right after {{{ var tag =
store.getTiddler(tiddler.tags[t]); }}}

Why is !tag in there as the first part of the OR formula? It looks
like it will never evaluate to true if there's a value for tag. It
will evaluate to true if tag is empty, but that would mean we've gone
through the entire tag list and are trying to keep going even though
we're inside of a for loop based on the length of that tag list,
right?

So why is that conditional an OR formula with !tag as one of the
components?

Sorry if I'm being completely daft.

Thanks,

Scott

Scott Steele

unread,
Jun 23, 2011, 6:56:02 PM6/23/11
to TiddlyWiki
Sorry all! After examining it further and playing around with
javascript in the live preview plugin, I found the answer to my
question about the conditional as well as the fix for my plugin.

In case anyone else with limited javascript experience wanted to know
the answer, the !tag in the if(!tag ||
tag.tags.contains("excludeLists")) conditional is there to prevent an
error. When it's referring to tag, it's not referring to the title of
the tag, but to a tiddler corresponding to that tag (e.g. if it were
excludeSearch, it wouldn't be checking to see if excludeSearch is an
entry in a tag list, it would be checking to see if there is a tiddler
named excludeSearch in the current TiddlyWiki or store). If tag
doesn't exist as an actual tiddler yet, calling
tag.tags.contains("excludeLists") would throw an error since it would
be querying a non-existent tiddler.

I'm sure this was obvious to anyone with any experience in serious
programming, but the fix to my plugin was to add a similar check in
the conditional if(!config.options.chkHttpReadOnly || !
tag.tags.contains(config.options.txtEditorOnlyTag))

The final plugin code is now the following:

//{{{


config.macros.tags.handler =
function(place,macroName,params,wikifier,paramString,tiddler)
{
params =
paramString.parseParams("anon",null,true,false,false);
var ul = createTiddlyElement(place,"ul");
var title = getParam(params,"anon","");
if(title && store.tiddlerExists(title))
tiddler = store.getTiddler(title);
var sep = getParam(params,"sep"," ");
var lingo = config.views.wikified.tag;
var label = null;
for(var t=0; t<tiddler.tags.length; t++) {
var tag = store.getTiddler(tiddler.tags[t]);
if(!tag || !tag.tags.contains("excludeLists")) {
if(!config.options.chkHttpReadOnly || (tag
&& !
tag.tags.contains(config.options.txtEditorOnlyTag))) {
if(!label)
label =
createTiddlyElement(ul,"li",null,"listTitle",lingo.labelTags.format([tiddle­
r.title]));


createTagButton(createTiddlyElement(ul,"li"),tiddler.tags[t],tiddler.title)­;
if(t<tiddler.tags.length-1)
createTiddlyText(ul,sep);
}
}
}
if(!label)


createTiddlyElement(ul,"li",null,"listTitle",lingo.labelNoTags.format([tidd­
ler.title]));



};


//}}}

(with {{{config.options.txtEditorOnlyTag = excludeSearch;}}} in my
configOptions tiddler)


Sorry for being completely daft!

Thanks,

Scott
> createTiddlyElement(ul,"li",null,"listTitle",lingo.labelTags.format([tiddle­r.title]));
>
> createTagButton(createTiddlyElement(ul,"li"),tiddler.tags[t],tiddler.title)­;
>                                 if(t<tiddler.tags.length-1)
>                                         createTiddlyText(ul,sep);
>                         }
>                 }
>         }
>         if(!label)
>
> createTiddlyElement(ul,"li",null,"listTitle",lingo.labelNoTags.format([tidd­ler.title]));

PMario

unread,
Jun 23, 2011, 7:02:10 PM6/23/11
to TiddlyWiki
On Jun 23, 11:56 pm, Scott Steele <scottlste...@gmail.com> wrote:
> The conditional I'm trying to understand is {{{ if(!tag || !
> tag.tags.contains("excludeLists")) }}}
> It comes right after {{{ var tag =
> store.getTiddler(tiddler.tags[t]); }}}
>
> Why is !tag in there as the first part of the OR formula? It looks
> like it will never evaluate to true if there's a value for tag. It
> will evaluate to true if tag is empty, but that would mean we've gone
> through the entire tag list and are trying to keep going even though
> we're inside of a for loop based on the length of that tag list,
> right?
>
> So why is that conditional an OR formula with !tag as one of the
> components?

var tag = store.getTiddler(tiddler.tags[t]);

In TW a tag can be a tiddler too. Plugins are tagged "systemConfig".
If you want, that systemConfig should be not listed, you can create a
tiddler named systemConfig tag it "excludeLists". it will not be
listed anymore.

so

store.getTiddler(tiddler.tags[t]) ... returns a tiddler with the tag
name.
If it exists the var tag will point to the tiddler object
If it doesn't exist (eg: there is no systemConfig tiddler) it returns
"null"

hope this helps.
-m

HansBKK

unread,
Jun 24, 2011, 1:24:25 AM6/24/11
to tiddl...@googlegroups.com
Excellent idea!

I've long thought that TW should distinguish, both in the UI and functionally, between "system" tags and "content" tags, i.e. those used to drive app functionality vs those used to indicate topics within the end-user content.

Looks like your plugin could be a first step in that direction - do you think it's robust enough to package and post to a public location?

HansBKK

unread,
Jun 24, 2011, 7:56:23 AM6/24/11
to tiddl...@googlegroups.com
talking to myself again, sorry

I was just checking out Tobias' TagSearchPlugin and it's got the ability to exclude specific tags, or those that are tiddlers tagged with an "exclude tag" (in my case "system"), so look's like what I need is already well in hand there, except perhaps for the built-in sidebar listings (which in my case are hopelessly overwhelming anyway. . .)

Just thought I'd mention it in case it helps the OP as well. . .

Scott Steele

unread,
Jun 24, 2011, 11:29:39 AM6/24/11
to TiddlyWiki
> I've long thought that TW should distinguish, both in the UI and
> functionally, between "system" tags and "content" tags, i.e. those used to
> drive app functionality vs those used to indicate topics within the end-user
> content.

The way I have my site set up really only distinguishes between casual
visitor mode and editor mode. If that is something that might be
useful to you, I'd recommend looking at BidiX's site: http://tiddlywiki.bidix.info/

It seems very polished with excellent use-case segregation (not only
between read-only and editor mode, but also between editor mode and
sys-admin mode).

I didn't use it because I had already built (read: installed plugins)
a lot of segregation structure around my current template. I might use
it in the future though.
Reply all
Reply to author
Forward
0 new messages