New in 5.5: Macro improvements

   —   
There was a lot of macro parameters in 5.0 already, so having twice as much in 5.5 seems almost unbelievable. Let's see what is new ...
Hi there,

As I noted in one of my previous posts, the macros belong to the part of the development where there is no exact plan what will be available in new version. The new options also depend on what we need for our new functionality and how much I can cover in my spare time (in case you don't need too much assistance and consulting ;-) ).

There is a lot of things done in 5.5 macros and sice standard documentation doesn't cover them (since it is often a last minute development), so I typically cover such things here. Let's see what has changed and what is new ...

Processing of the macro parameters

One major change was done on the processing side of the macros. In 5.0 and sooner, the macro parameters were pretty much just flags applied at the end of macro processing. So for example conversion was always done before equals, etc, the order of operation was basically hardcoded. With this, it also didn't make sense to use one parameter multiple times. The processing was done this way:
  1. Get the value selector
  2. Parse parameters and set flags
  3. Get the base value
  4. Apply the flagged parameters in the hardcoded order
  5. Do some post processing (handle SQL injection, encoding, recursion)
Yes, it was absolutely dummy, I totally agree with you. There actually was no need to make it smarter at that time.

5.5 is much better, providing macro resolving in form of state machine. This was basically done due to requirements of some new parameters, and also to provide better options in future (let's face it, macro engine is becoming so powerful that I already almost believe you will be able to make a page completely resolved as a macro :-) ) Let's see how the processing is done, that will give you the best picture:
  1. Get the value selector
  2. Parse the parameters and save them as a list
  3. Get the base value
  4. Apply parameters in the original order one by one, reusing result
  5. Do some post processing (handle SQL injection, encoding, recursion)
So the main improvements are having the list of parameters applied as they were put there. It also means that the same parameter can be applied several times as you process the macro value further and further. And the other thing is that macro resolver now internally used result in form of object, previously, it did all operations on the strings. This will mainly have great impact on macros in 6.0, which really will be mindblowing, trust me, we already have some prototypes being able to do unbelievable stuff.

New macro selectors

There are several nice macro selectors giving empty or constant values:
  • {%EmptyString%} - Returns String.Empty
  • {%Zero%} - Returns 0
  • {%Pi%} - Returns Math.PI
They can be used for various reasons, such as defining constants like this: {%Zero|(add)5%}

New mathematical operations

First of all, there are some improvement on the computational availability of the macros (if you need to make some more advanced calculations for some value):

|(divide)<value> - Is pretty much self-explanatory, it divides the value by the given number. Prior to this, you would have to multiply by 0.333333333... now it gets much easier with {%Something|(divide)3%}.

|(sin), |(cos), |(tan), |(sqrt) - Does corresponding goniometrial function with the result, you use it like {%Something|(sin)%}

|(pow)<value> - Computes base raised to given value exponent, use it like: {%Something|(pow)2%} which means Something2

New string manipulation

String manipulation functions are much more interesting, expanding the options to manipulate string the ways you can use in C#:

|(append)<string> - Apppends (suffixes) the given string to the value, e.g. {%Zero|(append)ABC%} returns 0ABC

|(prepend)string> - Prepends (prefixes) the given string to the value, e.g. {%Zero|(prepend)ABC%} returns ABC0

|(trim) - Removes the white spaces on the beginning and end of the value

|(trim)<chars> - Removes the given set of characters on the beginning and end of the value, e.g.

{%EmptyString|(append)ABCD|(trim)AD%} returns BC

|(trimend), |(trimend)<chars> - Does the trimming only on the end of the string

|(trimstart), |(trimstart)<chars> - Does the trimming only on the end of the string

|(padleft)<total width> - Makes sure that the string has total width of characters, filling the blanks with space

|(padleft)<total width>(with)<char> - Same as previous, but you can specify the filling character, so

{%Zero|(add)5|(padleft)3(with)0%} gives you 005

|(padright)<total width>, |(padright)<total width>(with)<char> - Same as previous, but with filling on the right side

|(substring)<start> - Gets the part of the string after the given index

|(substring)<start>;<length> - Gets the part of the string, e.g. {%CurrentDocument.DocumentName|(substring)1;3%}
  • Support of caching of the macro results - Say how this particular result should be cached
{#getmyvalue|(cacheminutes)10|(cachekey)MyValueOnThisPage#}

And probably some more in addition to this ...

This is all very closely connected to the better API (backwards compatible) where all objects and documents will be interconnected to a hierarchy which will also serve as LINQ to Kentico for querying data. I will elaborate some more on this later.

Now you finally see why I already almost believe you will be able to render entire page with macros in 6.0 :-), cause lot of this is already in stage of prototypes ...

See you next time!
Share this article on   LinkedIn

Martin Hejtmanek

Hi, I am the CTO of Kentico and I will be constantly providing you the information about current development process and other interesting technical things you might want to know about Kentico.

Comments

ralph commented on

I agree on the documentation part. Just played around with this stuff a bit. You can do amazing stuff with it. There is however a good page here that is listing all available macros: http://bit.ly/f2Rqnh

Ryan commented on

Good info! I wish there was documentation available that would describe all available macros though...without some searching I would have never found this posting. I think it would be great to greatly expand the Macros appendix in the documentation developer guide to show a list of all available macros, what they do, and what parameters are available. Thanks!

Martin Hejtmanek commented on

Hi Jeroen,

The parameters (functions) are always applied also on custom macros as before. You still get the full macro expression so you can parse it further. What is better is that the parameters are available through property MacroResolver.CurrentParameters as two-dimensional array of strings and you can manipulate with them.

Jeroen Fürst commented on

Hi Martin,

As usual great post! I was wondering if these new macro functions work with custom macro's and if it's easy to integrate even more custom functions in 5.5?

Jeroen

Martin Hejtmanek commented on

It was sort of a natural selection of having something easily readable and not coliding with anything else in the system or HTML.

Mark Prins commented on

Thanks Martin, the changes look great and will be very useful. I can't wait for version 6.0 now - very impressive functionality planned there!

One query, there might be a typo above, should the (handlesqlinhection) item be (handlesqlinjection)?

Mark

ctaleck IPAGlobal commented on

Is seems like you developing a new macro language. What is the reasoning behind the syntax of your macro system? Is there any precedent to how it looks or did you come up with this parenthesis and pipe concept internally?