System Variables: Details

Posted by ErichSteinboeck on 21 Mar 2009 12:11, last edited by ErichSteinboeck on 25 Jul 2009 12:07

Tags: include live system template variables

rating: +5+x

System Variables for your Wiki Page: Technical Details

Here you'll find a technical analysis of the Community How-To System Variables. If you just want to use the How-To, it is not necessary to understand the technical concepts presented here. Continue reading only if you'd like to understand more about the inner workings of Wikidot.

How the Idea Developed

To implement system variables for a Wikidot page you need variable, replaceable content. As an obvious candidate for any replaceable content are include variables, this automatically leads to the idea to include the Wikidot page from a live template. Once this concept is born, you'd think, that an implementation should be straightforward.

Far from it.

Here some of the challenges and chosen solutions are presented.

Basic Concept

Here's the basic concept, we're starting with: a live template directly includes its calling page, supplying all page variables as include variables.

[[include %%page_unix_name%%
| page_unix_name=%%page_unix_name%%
| page_name=%%page_name%%
.
.
]]

Trailing Consecutive Brackets

Challenge: Adding author=%%author%% to the above basic include poses the first challenge: as %%author%% resolves to [[*user user-name]], those two trailing consecutive closing brackets (“]]”) would break parsing of the [[include …]] statement.

Solution: two consecutive closing brackets only break parsing if the brackets are the very last characters on its line. To avoid such a situation, we will move the leading pipe (“|”) symbol in each line to the end of each line — so no two consecutive brackets can ever be at the very end of a line. In general, it is best that you always write your include like this (and not like the include example in the docs).

So we rewrite the include with trailing pipe (“|”) symbols:

[[include %%page_unix_name%%
page_unix_name=%%page_unix_name%% |
page_name=%%page_name%% |
author=%%author%% |
.
.
]]

Pipe Symbol in Internal Links

Challenge: Adding linked_title=%%linked_title%% to the above include poses another challenge: as %%linked_title%% resolves to [[[%%page_unix_name%%|%%title%%]]], the embedded pipe (“|”) symbol again breaks parsing of the [[include …]] statement.

Solution: The How-To Include variables with special characters suggests this workaround:

linked_title=[[[%%page_unix_name%%
[[include pipe{$br}]
%%title%%]]] |
br=]


where page pipe contains a pipe (“|”) symbol only.

As in our case we're able to rewrite the internal link to [/%%page_unix_name%% %%title%%]]], we'll use this simpler approach.1 Here's our code so far:

[[include %%page_unix_name%%
page_unix_name=%%page_unix_name%% |
page_name=%%page_name%% |
author=%%author%% |
linked_title=[/%%page_unix_name%% %%title%%] |
.
.
]]

Date

Challenge: Adding date=%%date%% presents the next challenge: as %%date%% resolves to [[date timestamp format="%e %b %Y, %H:%M %Z|agohover"]], the embedded pipe (“|”) symbol again breaks parsing of the [[include …]] statement.

Solution: There doesn't seem to be a way to transport [[date timestamp format="%e %b %Y, %H:%M %Z|agohover"]] to the calling page through an include variable. So we do two things:

  1. We remove the pipe (“|”) symbol in format="…|agohover" by specifying date=%%date|%e %b %Y, %H:%M %Z%% which resolves to [[date timestamp format="%e %b %Y, %H:%M %Z"]] which will work fine on the include. Note that this makes %%date%% slightly incompatible with {$date}, as the “… ago” hovering text is removed.

  2. To support the equivalent of the %%date|format-string%% page variable, two include variables are defined: {$date_start} and {$date_end}. When used together as in {$date_start}format-string{$date_end} the result is equivalent to %%date|format-string%%
    • To implement {$date_start} we add date_start=%%date|[!--%%--] to the [[include …]]. As %%…%% page variable parsing is done at an early stage (i. e. before [[include …]] parsing), it resolves to [[date timestamp format="[!--"]]--], which — if we ignore the trailing Wikidot comment — is equivalent to [[date timestamp format=". Exactly the first [[date …]] part that we need.
    • To implement {$date_end} we simply add date_end="]] to the [[include …]]

At this point our code looks like this:

[[include %%page_unix_name%%
page_unix_name=%%page_unix_name%% |
page_name=%%page_name%% |
author=%%author%% |
linked_title=[/%%page_unix_name%% %%title%%] |
date_start=%%date|[!--%%--] |
date_end="]] |
.
.
]]

Live Template

One might think that we've made it: the [[include …]] with all include variables has been defined properly. But …

Challenge: The code we wrote isn't recognized as a valid live template.

Solution: Live templates not only (as documented) must be named _template , but (not documented) they also must contain either %%content%% or %%content{number}%%, where number is a string comprised of digits 0…9 only.

Now, that's a challenge, because we do not want the page content added in addition to our include which already adds the page content.

One solution might be to add %%content{0}%%, which is sufficient for a template to be recognized as a live template. It will always resolve empty, as actual page section numbers start with one.

A different approach would be to add

[!--
%%content%%
--]

Again this would be enough for a live template to be recognized as such (it doesn't matter that %%content%% is surrounded by a Wikidot comment). But be aware that the comments would fail to hide all of the page content, if the content itself contained a Wikidot comment. The comment end tag (--]) of this comment would then prematurely end the surrounding comment from the above code!

For such a case, the Community How-To Nested Comments suggests the following solution:

[!--
[[code]]
%%content%%
[[/code]]
--]

But for now, let's assume we chose to add %%content{0}%% — this would make our code look like this:

[[include %%page_unix_name%%
page_unix_name=%%page_unix_name%% |
page_name=%%page_name%% |
author=%%author%% |
linked_title=[/%%page_unix_name%% %%title%%] |
date_start=%%date|[!--%%--] |
date_end="]] |
.
.
]]
%%content{0}%%

Preview

Did we finally make it? Everything working as intended? Unfortunately, no. What happens if — while editing your page content — you do a “preview” from the editor?

Challenge: During a “preview” just the above [[include …]] code is rendered: as code, and not as the processed include. No page content is shown at all! Our live template designed so far completely breaks “preview”.

Solution: As “preview” does not resolve %%…%% page variables of a live template, it will not resolve [[include %%page_unix_name%% …]] and as such does not show the page content as intended (if you'd save the page, everything worked fine, but we're looking for a solution for “preview” mode).

We could show the content during preview if we simply added %%content%%, but then it would show twice on the saved page: once through the include and a second time because of the added %%content%%. So we need a way to display %%content%% just during preview. Here is the chosen solution. We add the following code:

[[include %%category%%:_startcomment]]
%%content%%
[[include %%category%%:_endcomment]]

Where (within the same category)

page _startcomment contains

[!--
[[code]]

page _endcomment contains

[[/code]]
--]

As we saw before, neither [[include %%category%%:_startcomment]] nor [[include %%category%%:_endcomment]] is resolved during “preview” and page content will be shown — unfortunately along with the page content those [[include %%category%%:]] tags will also be shown as plain text.

When the page is saved, both [[include %%category%%:]] will be resolved and will completely comment (and thus remove) %%comment%%.

Page content is now shown properly both during preview and on the saved page, but as described above we still see [[include …]] code rendered as plain text during preview. Can we remove it? Here's a way: we'll surround the [[include …]] code with

[!--
[[code]]
[[include %%category%%:_endcomment]]


and

[[include %%category%%:_startcomment]]
[[/code]]
--]


We're again applying the idea presented above: the [[include %%category%%:]] are not resolved during preview and thus the [[include …]] code is commented by the Wikidot comment. When the page is saved the [[include %%category%%:]] are resolved and become empty Wikidot comments, leaving the [[include …]] intact.

Meanwhile our code looks like this:

[!--
[[code]]
[[include %%category%%:_endcomment]]
[[include %%page_unix_name%%
page_unix_name=%%page_unix_name%% |
page_name=%%page_name%% |
author=%%author%% |
linked_title=[/%%page_unix_name%% %%title%%] |
date_start=%%date|[!--%%--] |
date_end="]] |
.
.
]]
[[include %%category%%:_startcomment]]
[[/code]]
--]
[[include %%category%%:_startcomment]]
%%content%%
[[include %%category%%:_endcomment]]

User Variables

Challenge: In addition to system variables it may sometimes be desirable to define your own user variable that could be used on the page. If any piece of text or code is to be used multiple times on a page, such user variables may simplify page maintenance as any changes to the common part needs only to be done once.

Solution: By inserting %%content{2}%% to the list of include variables, it is possible to define user variables (in standard include variable syntax, like width=100px | name=standard.jpg in a second page section (separated from the main content by a content splitter ====).

Which gives us the final live template code:

[!--
[[code]]
[[include %%category%%:_endcomment]]
[[include %%page_unix_name%%
page_unix_name=%%page_unix_name%% |
page_name=%%page_name%% |
author=%%author%% |
linked_title=[/%%page_unix_name%% %%title%%] |
date_start=%%date|[!--%%--] |
date_end="]] |
.
.
%%content{2}%%
]]
[[include %%category%%:_startcomment]]
[[/code]]
--]
[[include %%category%%:_startcomment]]
%%content%%
[[include %%category%%:_endcomment]]

Related articles

Comments

Add a New Comment
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.