Dynamic Content with MiniCalc
Sage offers two pairs of tags, which use
MiniCalc to support dynamic content.
All four tags evaluate MiniCalc code,
which is supplied after the tag,
and terminated with an [end] tag.
The two "early" tags evaluate the MiniCalc code
as the Sage file is being parsed.
In contrast, the two "late" tags evaluate the MiniCalc code
as the Sage article is being served up.
The two "@" tags evaluate the MiniCalc expression,
and discard any result.
The two "=" tags evaluate the MiniCalc expression,
convert it to a string, and uses this string as follows:
[=early] | [@early] |
[=late] | [@late] |
- The [=early] tag parses the string as Sage content.
- The [=late] tag emits the string as HTML content.
Consider the following Sage code…
See Delphi's built-in
[url https://docwiki.embarcadero.com/Libraries/Alexandria/en/
System.ParamCount]`ParamCount`[end] and
[url https://docwiki.embarcadero.com/Libraries/Alexandria/en/
System.ParamStr]`ParamStr`[end] functions.
The above generates this content…
We can use MiniCalc to clean up the Sage code…
[@late]
function RadURL(Page, Caption);
const
Base = 'https://docwiki.embarcadero.com/Libraries/Alexandria/en/'
begin
$'<a href="${Base}${Page}">${Caption}</a>';
end;
[end]
See Delphi's built-in
`[=late]RadURL('System.ParamCount', 'ParamCount')[end]` and
`[=late]RadURL('System.ParamStr', 'ParamStr')[end]` functions.
This generates the same content as before…
A similar effect can be achieved
with the [@early] and [=early] tags…
[@early end=stop]
function RadURL(Page, Caption);
const
Base = 'https://docwiki.embarcadero.com/Libraries/Alexandria/en/'
begin
$'[url "${Base}${Page}"]${Caption}[end]'; // see note below
end;
[stop]
See Delphi's built-in
`[=early]RadURL('System.ParamCount', 'ParamCount')[end]` and
`[=early]RadURL('System.ParamStr', 'ParamStr')[end]` functions.
This generates the same content as before…
As noted above, the [=early], [@early],
[=late], and [@late] tags are not
allowed outside an article.
Additionally, each article is parsed and evaluated
in its own MiniCalc environment.
Thus, declarations from one article are not visible to others.
Fortunately, Sage does offer a way to share code across the
various articles in a volume: Volume Scripts.
A Volume Script is a MiniCalc file with the same name as
the Sage volume file,
but with the .mc file extension.
For example, the Volume Script for Info.vol.sage
would be Info.vol.mc (same folder).
When parsing a volume, and when generating an article, Sage
automatically executes the Volume Script (if any). The result of
the Volume Script is not used, but any functions or values
defined in the script will be accessible in MiniCalc throughout
the volume.
MiniCalc offers a way to include one MiniCalc file in another:
the @Include function.
To share code among several Sage volumes,
place the code in a single .mc file,
and each volume's Volume Script can include this file.
For example, suppose a folder contains
A.vol.sage and B.vol.sage.
In this same folder,
if the file Shared.mc contains shared code,
A.vol.mc and B.vol.mc would both contain this line:
@Include('Shared.mc');
The included file may be in a sub-folder, a parent folder, etc,
but it must reside under the Sage Library Root folder.
In Code Vault, and therefore on disk,
we tend to organize volumes in a hierarchy,
and this is reflected in the
Volume Tree.
This creates a problem for sharing code across volumes.
Consider how to share code between these two volumes:
\Enterprise\Libraries\Database\VDB\VDB.vol.sage
\Enterprise\Applications\GUI\VDB Explorer\VDBExplorer.vol.sage
In each of the Volume Scripts,
we would include a shared MiniCalc file.
If that file resides in the Enterprise folder
from the above hierarchy
(the common ancestor between the two volumes), then…
@Include('..\..\..\Shared.mc');
This is bad enough on its own,
but it also means that we'd need to edit the Volume Script
if we move the volume folder up or down in the tree.
Sage provides a solution to this issue:
the <Scripts> virtual folder.
MiniCalc filenames can use <Scripts> to refer to the
top-level Scripts folder under the Sage Library Root.
For example, if we move the Shared.mc file from under
\Enterprise to \Scripts\Enterprise, then…
@Include('<Scripts>\Enterprise\Shared.mc');
This way, we don't spend all day counting dots,
and if volumes move up or down in the tree,
this path remains accurate.
It also makes it a breeze to share code across departments.
In MiniCalc code, the Sage.LightTheme and Sage.DarkTheme
variables allow you to customize dynamic Sage content
based on the user's theme choice.
For example…
[@late]
BGColor := Sage.DarkTheme ? '#404040' : '#E0E0E0';
FGColor := Sage.DarkTheme ? 'orange' : 'maroon';
FontStyle := @Format('background-color:%s;color:%s', [BGColor, FGColor]);
[end]
[=late]'<font style="' + FontStyle + '"> Important </font>'[end]
The above generates this…
Important
To see the two options,
toggle the Sage Theme
in your web browser.
Important
MiniCalc code has access to an object named Sage,
which offers the following properties…
Property | Type | Notes |
---|---|---|
DarkTheme | Boolean | Not available to "early" tags; Indicates whether the dark theme is active. |
IsEarly | Boolean | If True, the Sage volume is being parsed; if False, a Sage article is being generated. |
IsLate | Boolean | If True, a Sage article is being generated; if False, the Sage volume is being parsed. |
LightTheme | Boolean | Not available to "early" tags; Indicates whether the light theme is active. |
OnError | function |
You can call this function to generate a Sage
hint, warning, or error.
The function takes between 2 and 4 arguments…
|
ParserMode | Enumeration | Choices are: @smAuthoring, @smCompiling, or @smServing. |
⏱ Last Modified: 10/24 10:44:32 am