Welcome

BoltWire is a content management system developed by Dan Vis.

Welcome Tour
Documentation
Mailing List



Popular Posts

Version 5.11 Released
May 26, 2016

Big Changes Coming Soon...
April 28, 2016

Catching Up
April 6, 2016



Other Sites

Here's some other sites by Dan Vis:

Alexa Echoes
Join my adventures developing for Amazons exciting new voice platform.

Firefly Spot
Personal rambling about new gadgets, technology news, and space travel.

FAST Missions
My ministry hub, with news and updates about our online school.

You can follow him at www.danvis.info.

Functions

Documentation > Handbook > Functions

Commands are used to generate dynamic content and create various effects.

Here's a list of commands currently available in BoltWire. Click one for more info:

breadcrumb
counter
embed
forward
highlight
include
index
info
lastmodified
list
log
login
logout
mail
math
memberships
preview
random
script
search
source
tags
time
toc
translate

Functions vs Commands

Commands and functions are similar in BoltWire. The difference is that functions are processed immediately when a page loads, whereas commands are processed only after the form containing them submits. Consider the following example:

[(mail to=somewhere@boltwire.com from={~email} subject='I visited page {p}' body=template.mail)]

This is a function--causing an email to be sent by simply viewing the page it is written on. Everytime you revisit or reload the page, another email is sent. It gets the return email address from the user's member page--assuming that information is stored there as a data variable. The page name will be showed in the subject line. The body of the message comes from a template.

A command allows you receive data from the user and then send the mail only after they submit that information. Here is a more useful example:


[form]
Subject: [text subject]
Message:
[box message rows=5 cols=50][box]
[submit]
[command mail to=somewhere@boltwire.com from={~email} subject={=subject} body={=message)]
[form]

It looks similar to the function, but it inserts the subject and message supplied by the user into the email. I could have gotten the "from" email from a text input field if desired, but decided to use one already in the system.

Constructing Functions

There are actually different kinds of functions with only a slightly different syntax. All three begin with the word function, and are followed by the name of the function. You can put as many parameters in a function as desired. If there are spaces in the value (or any parameter argument) be sure to enclose it with quote marks.

The three type of functions have to do with the order of markup processing. In many cases it will not matter which you use, but in other situations it can make a signficant different. Here are the three formats and what they are called in BoltWire:

Variable Functions
Normal Functions
Conditional Functions   

Initially, BoltWire used the normal function syntax. So the breadcrumb function for this page looks like:


[(breadcrumb {p})]

Documentation > Handbook > Functions

In time, the variable functions were added as a way to use function outputs as parameters values in other functions, so the syntax was created and the markup was added earlier in the markup table.

The conditional functions were added as a way to have functions that only execute when a conditional passes, so that syntax was added, and it was placed in the markup table after conditional were processed.

Examples

Suppose you had forum pages like forum.1000, forum.1001, forum.1002 up to forum.1100, and you wanted to forward a user to a random page. Notice how the random function is used to set the parameter for the forward function:

[(forward forum.'{(random 1000 1100)}')]

This uses the info function to generate a list of page names all drawn from the page info.counter, and then it feeds them into the list function, which is processed slightly later to generate a report.

[(list '{(info list page=info.counter)}' fmt='{+p}')]

Suppose now I wanted to forward all admins to a special page. If I use a variable or normal function, the page will always forward, because the functions are processed before the conditional is ever checked:

[if admin]{(forward special.page)}[if]
[if admin][(forward special.page)][if]

If I use a conditional function, the condition is processed first, and the forwarder only goes into effect if the user is an admin (what I want):

[if admin]<(forward special.page)>[if]

Sometimes you will get the right output, but waste processing time. In the following example, both searches are performed, and then one is displayed. This increase processing time and will cause your page to take longer to load. A variable function would be the same:

[if equal {p1} forum][(search group=forum)][else][(search group=blog*)][if]

Because a conditional function is processed later, the conditional is evaluated first, and then only one search performed and displayed. It would look exactly but on a large site, the page could load much more quickly.

The reverses is also true. Only variable and normal functions can be used inside a conditional. Suppose you had a group of pages, each with a timestamp of their creation date in {p2}. If you wanted to check whether a page was created after a certain date I could do this:

[if more {+p2} {(time 'January 1, 2010' timestamp)}]Yes [else]False [if]

The time function generates a timestamp for the date in question, then the conditional compare it to the page name. A normal function would also work. If I used the following, the conditional would not perform as expected, because the timestamp is not yet returned when the conditional is evaluated:

[if more {+p2} <(time 'January 1, 2010' timestamp)>]Yes [else]False [if]

Here are two other situations where the type of function you use is important. Consider this example:

[(search group=blog if="equal Tuesday {(time '{+p2}' %A)}")]

This conditional will fail because BoltWire will try to process the time function first (and will give an error because { p2} is not recognizable). When it gets to the search function, the conditional is mangled and will not generate the desired results. To fix it, change time to a conditional function. BoltWire will hit the search function first with the if parameter intact. The same principle would apply if you specified an inline template (or fmt) in the search above. If it contained a variable function, the output would be jumbled--you would have to have a conditional function.

It is even possible to nest three levels of functions, where you use the ouput of a variable function to determine the output of a normal function, which in turn is used to shape the output of a conditional function!

Note: If you try to nest one function within another that is the same type (ie variable, normal, or conditional) the markup will fail as BoltWire will see the closing tag of the interior function and think it is the end of the outer function.

Summary

In most cases, it does not matter which type of function you use--all three work essentially the same. As a rule of thumb, use a normal function most of the time. If you are putting a function inside a condition, use a conditional function. If you are using one function to generate a parameter inside another function, use the variable function (inside). If it is used in an if, template, or fmt parameter and it needs to be available to the outer function in an unprocessed form, use a conditional function.

Everything makes sense if you just remember the order of processing in the markup table. In a highly simplified form, markup is processed in this order:

escapes
variables
variable functions
normal functions
conditionals
conditional functions
everything else

For more information about the markup table?, click here.

Function Messaging

The BoltWire messaging system extends to functions, though it is turned off by default. That is, functions sometimes generate messages--but they are not seen unless you turn them on. To turn on the messages coming back from an individual function, add messages=true to the parameters of the function. To turn them on sitewide, set funcMessages: true in site.config. You can also turn them on dynamically in config.php or a plugin by changing the config value based on your needs. This might be useful if you only want admins to see these messages. Not all functions have messaging. More should be added.

Advanced Function Features

BoltWire has a number of advanced features connected with functions worth mentioning here. Some are slightly experimental or only work in certain situations. Use with caution.

1) Conditionals. You can add an 'if' parameter to any function and fully tap into BoltWire's conditional system. In the example below, the function only processes if the current use is Bob. IE, only Bob is sent to a page telling him he is blocked.

[(forward action.blocked if='equal bob']

2) Translations. Suppose you are using a French language file. Function names are automatically converted from French to English. So [(chercher ...)] is read as if it were [(search ...)].

3) Stop Watch. You can test how long it takes to perform the various functions in your form by setting $BOLTstopWatch to 'functions' in index.php before calling the engine. To see all functions and commands set it to 'all'. To only see commands set it to 'commands'. For commands, you also have to abort the form before it completes or the stopwatch results will disappear when the page reloads. The easiest way to do this is to temporarily add [command warn 'Abort for stopwatch'] just before the close of the form.

If you want to report the time for specific commands/functions, set $BOLTstopWatch to 'true' (or one of the other options) and then add stopwatch=true as a parameter to any command or function you wish. The times will appear immediately after the line that says "Page construction begun".

4) Output. You can modify the output of a function (the value passed back to the page after processing) by setting an output parameter to one of several options: output=false supresses all output. output=html returns the escaped html of the normal output. output=nolines replaces line breaks with a single space. output=csv replaces line breaks with commas to generate a csv list. You can also set escape=true to escape the content.

Toolmapping.

Toolmapping allows you to point a core function to a custom script, effectively overwriting the default behavior of the function. Suppose you wanted to customize how the counter function works. Simply add the following line to index.php or config.php or a plugin, and when the counter function is called, BoltWire will reroute the parameters to BOLTFmycounter (your script), rather than BOLTFcounter (the default script):

$BOLTtoolmap['f']['counter'] = 'mycounter';

It also works the opposite way. The following line would essential create a new "mycounter" function that maps to the default counter function and works exactly the same:

$BOLTtoolmap['f']['mylogin'] = 'login';

Toolmapping is a very powerful feature for customizing how BoltWire works. BoltWire can also remap commands (change the 'f' to 'x') and conditionals (change the 'f' to 'c').

Developer Information

All the functions available to BoltWire are included in functons.php and they are arranged in alphabetical order. There are three function markups in markups.php (variable functions, regular functions, and conditional functions) and functions in markups.php and library.php that helps process functions.

To develop a custom function simply create a function prefixed by BOLTF modeled on one similar to your needs. Then add it to the config.php file or a plugin. It then becomes instantly available to your site. Suppose you wanted to create a function that inserts a copyright notice on your site. You could use the following php function and then insert the markup below it.


function BOLTFcopyright($args) {
     $year = strftime('%Y');
     return 'Copyright $year. All rights reserved.';
     }

[(copyright)]

You could of course do this easily with the time function using only core BoltWire functionality. Just put "Copyright [(time %Y)]..." This is just an example.

If you create a custom function it can be combined with other functions and all of BoltWire's built in systems. This means to do something quite complex you probably only need to add one or two small pieces to BoltWire's already robust core. If BoltWire can't get you all the way to your goal, it can definitely help get you most of the way!

If you develop an especially useful function consider posting it in the Solution Area at BoltWire so others can use your code.

To leave a comment, please login using your Facebook account: