E130 / S130 Tags

Options

I recently discovered the E130 / S130 tag and how useful it can be. Unfortunately, I also discovered how difficult it is to figure out. There is no documentation on the E130 tag, and most discussions about E130 in the Community were stripped of their code during the migration a while back. [[E130:help]] at least provides a list of available operators, but doesn't really explain what each operator does.

 

Here is what I've found for anyone who is interested, and so there is at least some introductory E130 info searchable in the Community. :smileyhappy:

 

The first thing to note about E130/S130 tags is that they evaluate based on Reverse Polish Notation. In RPN, the operator comes after the items it is evaluating, so 1 + 2 in RPN would be 1 2 +.

 

RPN expressions are also evaluated in stack structure, which basically means that new items added to the expression are stacked on top of the previous items. This is called a "push." A visual representation of the stack created by the expression 1 2 would be:


2

1


The operators remove (or "pop") a certain number of items from the top of the stack, evaluate them, and push the result to the stack. After the entire expression has been evaluated, the value on the top of the stack is returned. Ideally there would be only one value left. Here is an example expression, shamelessly stolen from Wikipedia:


5 1 2 + 4 * + 3 -


InputWhat does it do?Current Stack5Push (5)51Push (1)152Push (2)215+Pop two values (1, 2), calculate sum, and push result (3)354Push (4)435*Pop two values (3, 4), calculate product, and push result (12)125+Pop two values (5, 12), calculate sum, and push result (17)173Push (3)317-Pop two values (17, 3), calculate difference, and push result (14)14

 

 

(Check out the Wikipedia article on Reverse Polish Notation for much more detailed information about RPN.)

 

As I mentioned earlier, [[E130:help]] or [[S130:help]] will render a list of available operators, but doesn't really explain what each operator does. I've muddled through the operators to try to figure this own on my own, and here's what I've come to understand about them.

 

Operators in pink are ones I'm not sure about the application/usefulness of.

 

OperatorNumber of ArgsWhat does it do?<                      2                      Pops the top 2 items (X,Y) from the stack, evaluates whether or not X is less than Y, pushes result to stackText values will be evaluated as the number 0[[S130: X Y < ]]Evaluates if X is less than YTrue = 1False = 0[[S130: 1 2 <]]Returns 1[[S130: 2 1 <]]Returns 0[[S130: "b" 2 < ]]Returns 1 ("b" is evaluated as 0, and 0 is less than 2)[[S130: 2 "q" < ]]Returns 0 ("q" is evaluated as 0, and 2 is not less than 0)[[S130: a b <]]Returns 0 (0 is not less than 0)int           1           Pops the top item from the stack, then pushes its nearest integer[[S130: 1 int ]]Returns 1[[S130: 1.6 int ]]Returns 2[[S130: 1.4 int ]]Returns 1[[S130: "a" int ]]Returns 0 (since a is not a numeric value)copy                           1 (2?)                           As far as I can tell, this pops the previous two items (X,Y) from the stack and copies the text of X over the text of Y, then pushes the two items, now (X,X), back onto the stack. The :help info says this requires 1 argument, but I only see results using at least 2.[[S130: 1 copy ]]No output[[S130: 1 copy printstack]]No output[[S130: 1 2 copy ]]No output[[S130: "a" copy ]]No output[[S130: "a" "b" copy ]]Returns a[[S130: "a" "b" copy printstack ]]Returns ["a","a"] (both items are still present in the stack)[[S130: "a" "b" "c" "d" copy printstack ]]Returns ["a","a","c","c"][[S130: "a" "b" "c" "d" copy copy printstack ]]Returns ["a","a","c","c"]&&              2              Pops the previous 2 items from the stack, then returns whether or not both are true[[S130: X Y < Q Z < &&]]Evaluates if X is less than Y and Q is less than ZTrue = 1False = 0[[S130: 1 4 < 2 4 < &&]]Returns 1[[S130: 1 4 < 8 4 < &&]]Returns 0[[S130: 6 4 < 8 4 < &&]]Returns 0printstack                   0                   Creates a string of the entire stack, then pushes that string on to the end of the stack(This is incredibly useful for testing!)[[S130: 5 2 printstack]]Returns ["5","2"][[S130: 5 2 printstack printstack]]Returns ["5","2","[\\"5\\",\\"2\\"]"][[S130: 5 2 < printstack]]Returns ["0"][[S130: 5 2 < printstack printstack]]Returns ["0","[\\"0\\"]"][[S130: "http://community.convio.com/t5/forums/recentpostspage/post-type/message/category-id/Community" "some text" printstack printstack]]Returns ["http:\\/\\/community.convio.com\\/t5\\/forums\\/recentpostspage\\/post-type\\/message\\/category-id\\/Community","some text","[\\"http:\\\\\\/\\\\\\/community.convio.com\\\\\\/t5\\\\\\/forums\\\\\\/recentpostspage\\\\\\/post-type\\\\\\/message\\\\\\/category-id\\\\\\/Community\\",\\"some text\\"]"]concat                   2                  Pops the previous 2 items from the stack, concatenates them, then pushes the result to the stack[[S130: X Y concat]]Returns XY[[S130: 1 2 concat]]Returns 12[[S130: 1 2 concat 3 < ]]Returns 0 (false, since 12 is not less than 3)[[S130: 1 2 "three" concat printstack]]Returns ["1","2three"][[S130: 1 2 "three" concat concat]]Returns 12three[[E130: [[S8]] "#" 1 2 < "true" "false" ? concat concat]]Returns http://www.yourdomain.org/path/page.html#truenextindexof              3              Pops the previous 3 items (X,Y,Z) from the stack, then returns the next index of Y in X after Z index[[S130: "abcdefghijklmnop" "k" 2 nextindexof]]Returns 10 (The next time k is in the string after index 2 [c] is index 10)[[S130: "abcdefghijklmnop" "k" 13 nextindexof]]Returns -1 (error, k does not appear again in the string after index 13)[[S130: "the rain in the spain lies mainly on the plain" "the" 10 nextindexof]]Returns 12 (index 10 starts "n the spain lies...")[[S130: "the rain in the spain lies mainly on the plain" dup "spain" indexof "the" swap nextindexof]]Returns 37 (the index of "spain" is 16, the next index of "the" after 16 is 37)/          2          Pops the previous 2 items (X,Y) from the stack, divides X by Y, then returns the quotient to the stack[[S130: 1 2 /]]Returns 0.5[[S130: 10 2 /]]Returns 5[[S130: 1 10 2 / printstack]]Returns ["1","5"]-          2          Pops the previous 2 items (X,Y) from the stack, subtracts Y from X, then returns the difference to the stack[[S130: 1 2 -]]Returns -1[[S130: 10 2 -]]Returns 8[[S130: 1 10 2 - printstack]]Returns ["1","8"]replaceall    3    Pops the previous 3 items (X,Y,Z) from the stack, replaces every instance of Y with Z in the string X, then returns the result to the stack[[S130: "your house, your car, your money" "your" "my" replaceall]]Returns my house, my car, my moneypop         1         Removes the previous item from the stack[[S130: 1 2 pop]]Returns 1[[S130: 1 2 pop printstack]]Returns ["1"][[S130: 1 2 pop 3 printstack]]Returns ["1","3"]dup          1          Returns a duplicate of the previous item to the stack[[S130: 1 2 dup printstack]]Returns ["1","2","2"][[S130: 1 2 dup 3 printstack]]Returns ["1","2","2","3"][[S130: "the rain in the spain lies mainly on the plain" dup "spain" indexof "the" swap nextindexof]]Returns 37+         2         Pops the previous 2 items from the stack, then returns their sum to the stack[[S130: 1 2 +]]Returns 3[[S130: 10 2 +]]Returns 12[[S130: 1 10 2 + printstack]]Returns ["1","12"]currency         1         Pops the previous item from the stack, then returns it to the stack as a currency value[[S130: 1 currency]]Returns $1.00[[S130: 10 3 / currency]]Returns $3.33 (10/3=3.333333333... rounded to the nearest cent)[[S130: 20.13567 currency]]Returns $20.14*    2    Pops the previous 2 items from the stack, multiplies them, and returns the product to the stack[[S130: 10 2 *]]Returns 20stringcount    2    Pops the previous 2 items (X,Y) from the stack, counts how many times Y appears in X, then returns the count to the stack[[S130: "the rain in the spain lies mainly on the plain" "the" stringcount]]Returns 3number                    1                    Pops the previous item from the stack and returns it as a numeric value. In all tests I've done, though, numbers and strings are able to be used interchangeably.[[S130: "asdf" number]]Returns 0[[S130: "20" number 5 +]]Returns 25[[S130: "20" 5 +]]Still returns 25[[S130: "3adfs23 fdakj9" number ]]Returns 3239[[S130: "20.345" currency number]]Returns 20.34[[S130: "20.345" currency 2 *]]Returns 40.68lastindexof       2       Pops the previous 2 items (X,Y) from the stack, then returns the index of the last time Y appears in X[[S130: "the rain in the spain lies mainly on the plain" "the" lastindexof]]Returns 37[[S130: "blah" 1 "the rain in the spain lies mainly on the plain" "the" lastindexof printstack]]Returns ["blah","1","37"]roundmult       2       Pops the previous 2 items (X,Y) from the stack, rounds X to the nearest multiple of Y, then returns the result[[S130: 15.4 2 roundmult]]Returns 16[[S130: 2.99 3 * 1 roundmult]]Returns 9length      1      Pops the previous item from the stack and returns its length in characters[[S130: "the rain in the spain lies mainly on the plain" length]]Returns 46[[S130: 999 length]]Returns 3!   1   Pops the previous item from the stack and toggles true/false (1/0)[[S130: 2 5 < !]]Returns 0 (false) because it is true that 2 is less than 5substring    3    Pops the previous 3 items from the stack (X,Y,Z) and returns a substring of X, starting at index Y and ending at index Z[[S130: "the rain in the spain lies mainly on the plain" 4 40 substring]]Returns rain in the spain lies mainly on themax   2   Pops the previous 2 items from the stack and returns whichever is larger[[S130: 5 2 max]]Returns 5indexof         2         Pops the previous 2 items (X,Y) from the stack and returns the index of Y in X[[S130: "the rain in the spain lies mainly on the plain" "spain" indexof]]Returns 16[[S130: "the rain in the spain lies mainly on the plain" "spain" indexof printstack]]Returns ["16"][[S130: "the rain in the spain lies mainly on the plain" dup "spain" indexof printstack]]Returns ["the rain in the spain lies mainly on the plain","16"]stackcount         0         Counts the number of items in the stack, then returns the result to the stack[[S130: 2 5 stackcount]]Returns 2, since there are two items left in the stack[[S130: 2 5 3 4 2 1 + - * + + stackcount]]Returns 1, since 2 5 3 4 2 1 + - * + + evaluates to just ["10"][[S130: 2 5 3 4 2 1 + - * + + stackcount printstack]]Returns ["10","1"]min    2    As far as I can tell, this pops the previous 2 items from the stack and returns whichever is smaller[[S130: 5 2 min]]Returns 2string        1        Pops the previous item from the stack and returns it as a text string. In all tests I've done, though, numbers and strings are able to be used interchangeably.[[S130: "20.345" currency string]]Returns $20.34[[S130: "20.345" currency 2 * string]][[S130: "20.345" currency string 2 *]]Both return 40.68swap          2          Pops the previous 2 items (X,Y) and swaps their position, returning (Y,X) to the stack[[S130: 1 2 swap printstack]]Returns ["2","1"][[S130: 1 2 3 swap 4 printstack]]Returns ["1","3","2","4"][[S130: "the rain in the spain lies mainly on the plain" dup "spain" indexof "the" swap nextindexof]]Returns 37compare                       2                      Pops the previous 2 items (X,Y) and evaluates the difference between their ASCII decimal values.[[S130: 2 5 compare]]Returns -3[[S130: 13 2 compare]]Returns -1 (1 is 1 less than 2)[[S130: 13 29 compare]]Returns -1 (remember, first character/digit only... not sure how this is useful...)[[S130: "a" "z" compare]]Returns -25[[S130: "z" "a" compare]]Returns 25[[S130: "asdf" "jkl" compare]]Returns -9 (This might be useful for sorting/grouping alphabetically somehow?) [[S130: 0 "!" compare]]Returns 15  (0's decimal value is 48, !'s decimal value is 33, 48 - 33 =1 5) help 0 Renders a list of available operators and the message "PC LOAD LETTER" print             1             Renders the previous item regardless of the remaining operations[[S130: 2 1.4 print "asdf"]]Returns 1.4asdf[[S130: 2 1.4 print "asdf" printstack]]Returns 1.4["2","1.4","asdf"][[S130: 2 1.4 print "asdf" pop -]]Returns 1.40.6 (Prints 1.4, then pops "asdf" out of the stack and evaluates 2-1.4, resulting in 0.6)[[S130: 2 1.4 print "asdf" pop - printstack]]Returns 1.4["0.6"] (Note how that 1.4 is only printed, not part of the stack)||               2               Pops the previous 2 items (X,Y) from the stack and evaluates whether or not either X or Y is true[[S130: X Y < Q Z < ||]]Evaluates if X is less than Y or Q is less than ZTrue = 1False = 0[[S130: 1 4 < 2 4 < ||]]Returns 1[[S130: 1 4 < 8 4 < ||]]Returns 1[[S130: 6 4 < 8 4 < ||]]Returns 0?         3         Pops the previous 3 items (X,Y,Z) from the stack and returns Y if X is true, or Z if X is false[[S130: 1 2 < "1 is less than 2" "2 is less than 1... wait, no it's not, what's going on?!" ?]]Returns 1 is less than 2[[S130: 2 1 < "asdf" "jklsemicolon" ?]]Returns jklsemicolon[[E130: [[S8]] "#" 1 2 < "true" "false" ? concat concat]]Returns http://www.yourdomain.org/path/page.html#true>                             2                             Pops the previous 2 items (X,Y) from the stack, then returns whether or not X is greater than YText values will be evaluated as 0[[S130: X Y > ]]Evaluates if X is greater than YTrue = 1False = 0[[S130: 1 2 >]]Returns 0[[S130: 2 1 >]]Returns 1[[S130: "b" 2 < ]]Returns 1 ("b" is evaluated as 0, and 0 is less than 2)[[S130: 2 "q" < ]]Returns 0 ("q" is evaluated as 0, and 2 is not less than 0)[[S130: a b <]]Returns 0 (0 is not less than 0)[[E130:[[E98:days:after:[[S1:last_trans_date]]:MMM dd, YYYY]] [[E98:days:after:[[S1:external_last_gift_date]]:MMM dd, YYYY]] > "Last transaction was on [[S1:external_last_gift_date]] for [[S1:external_last_gift_amount]]." "Last transaction was on [[S1:last_trans_date]] for [[S1:last_trans_amount]]." ?]]Using an account with External Last Gift Date of Apr 17, 2012 and Last Transaction Date of Oct 10, 2012:Returns Last transaction was on Oct 10, 2012 for $5.00.==                    2                    Pops the previous 2 items from the stack and returns whether or not they are numeric equals.This appears to work for dates in addition to numbers, but not text.[[S130: 1 2 ==]]Returns 0[[S130: 10 3 - 7 ==]]Returns 1[[E130: "[[S1:external_last_gift_date]]" "[[S9:CalendarList]]" ==]]Using an account with External Last Gift Date of Apr 17, 2012 to test on Mar 8, 2013:Returns 0Using an account with External Last Gift Date of Mar 8, 2013 to test on Mar 8, 2013:Returns 1[[E130: "[[S1:external_last_gift_date]]" "[[S9:CalendarList]]" printstack]]Returns ["Mar 8, 2013","Mar 8, 2013\\n"] (The \\n newline escape doesn't appear to be evaluated)[[S130: "asdf" "jklsemicolon" ==]]Returns 1 ("asdf" and "jklsemicolon" are text, so both their numeric values are 0.)

 

Most of my examples use S130 rather than E130. This is because E-Tags are only used when one of the items in the expression is an S-Tag itself, so they render in the correct order for evaluation.

 

When evaluating S-Tags, it may also be necessary to enclose them in a T-Tag. The T-Tag documentation explains that T8 was made specifically for use with arguments to the E130 tag, but I also used T1 and T5 in this example.

Tagged:

Comments

  • This is awesome. That tag has been far too intimidating for far too long. Thanks, Chris!



  • Very well done. Another win.

     

    / I don't see any pink operators.

  • Brian Mucha:



    Very well done. Another win.

     

    / I don't see any pink operators.




    Brian Mucha wrote:



    I don't see any pink operators.


    D'oh!  It stripped out the background-color when I posted... I'll fix it now, thanks for pointing that out.

     

    Edit:  Ugh, it doesn't allow valign, either.  I might reformat that later to make it more readable.

  • Chris Backus:



    Brian Mucha wrote:



    I don't see any pink operators.


    D'oh!  It stripped out the background-color when I posted... I'll fix it now, thanks for pointing that out.

     

    Edit:  Ugh, it doesn't allow valign, either.  I might reformat that later to make it more readable.

    "Pops the previous item from the stack and returns it as a numeric value. In all tests I've done, though, numbers and strings are able to be used interchangeably."

     

    What if you try with a operator that works differently on strings and numbers such as 'compare'?

     

    Edit: 

     

    [[S130: "$30" "6" compare]]  = -18

     

    [[S130: "$30" number "6" compare]]  = -3

     

  • Brian Mucha:

    "Pops the previous item from the stack and returns it as a numeric value. In all tests I've done, though, numbers and strings are able to be used interchangeably."

     

    What if you try with a operator that works differently on strings and numbers such as 'compare'?

     

    Edit: 

     

    [[S130: "$30" "6" compare]]  = -18

     

    [[S130: "$30" number "6" compare]]  = -3

     




    Brian Mucha wrote:

    "Pops the previous item from the stack and returns it as a numeric value. In all tests I've done, though, numbers and strings are able to be used interchangeably."

     

    What if you try with a operator that works differently on strings and numbers such as 'compare'?

     

    Edit: 

     

    [[S130: "$30" "6" compare]]  = -18

     

    [[S130: "$30" number "6" compare]]  = -3

     


     

    That's an interesting point, I hadn't even considered symbols...  In that example, though, you could also convert "6" to currency:

     

    [[S130: "$30" currency "6" currency compare]]   =  -3

     

    However, [[S130: "$30" "6" currency compare]]  = -3  as well...  Check out this post...  (It's from 2009, so the formatting has gone a bit wonky.)  About 1/3 into the post:




    Linton Myers wrote:



    The stack handles two types of data&colon; a "string" (internally, a String) and a fixed point "number" (internally a Java double) with automatic conversion between types as needed and with generous interpretation when parsing numbers, e.g. "$5.20" will parse as 5.2 and "foo" will parse as 0.

     




    In [[S130: "$30" "6" currency compare]], even though "$30" is technically text,  the operator recognizes that both values appear to be currency and compares the first number, rather than the "$" symbol, to the number 6.

     

     

     

    Also, playing with that I've realized that the compare operator is comparing the decimal value of the first character in X to the decimal value of the first character in Y.:

     

    [[S130: 0 "!" compare]]  =  15  (0's decimal value is 48, !'s decimal value is 33, 48 - 33 =1 5)

     

    (I'll update the first post to clarify this.)

  • Chris Backus:



    Brian Mucha wrote:

    "Pops the previous item from the stack and returns it as a numeric value. In all tests I've done, though, numbers and strings are able to be used interchangeably."

     

    What if you try with a operator that works differently on strings and numbers such as 'compare'?

     

    Edit: 

     

    [[S130: "$30" "6" compare]]  = -18

     

    [[S130: "$30" number "6" compare]]  = -3

     


     

    That's an interesting point, I hadn't even considered symbols...  In that example, though, you could also convert "6" to currency:

     

    [[S130: "$30" currency "6" currency compare]]   =  -3

     

    However, [[S130: "$30" "6" currency compare]]  = -3  as well...  Check out this post...  (It's from 2009, so the formatting has gone a bit wonky.)  About 1/3 into the post:




    Linton Myers wrote:



    The stack handles two types of data&colon; a "string" (internally, a String) and a fixed point "number" (internally a Java double) with automatic conversion between types as needed and with generous interpretation when parsing numbers, e.g. "$5.20" will parse as 5.2 and "foo" will parse as 0.

     




    In [[S130: "$30" "6" currency compare]], even though "$30" is technically text,  the operator recognizes that both values appear to be currency and compares the first number, rather than the "$" symbol, to the number 6.

     

     

     

    Also, playing with that I've realized that the compare operator is comparing the decimal value of the first character in X to the decimal value of the first character in Y.:

     

    [[S130: 0 "!" compare]]  =  15  (0's decimal value is 48, !'s decimal value is 33, 48 - 33 =1 5)

     

    (I'll update the first post to clarify this.)

    Can this PLEASE be added to the documentation at https://secure2.convio.net/customer/luminate_online/v11/s-tags/S-Tags.htm??? Pretty please?

     

    This makes me sad: https://secure2.convio.net/customer/luminate_online/v11/s-tags/S-Tags.htm#search-S130

     

     

    Your search for "S130" returned 0 result(s)

  • Bo Bell:

    Can this PLEASE be added to the documentation at https://secure2.convio.net/customer/luminate_online/v11/s-tags/S-Tags.htm??? Pretty please?

     

    This makes me sad: https://secure2.convio.net/customer/luminate_online/v11/s-tags/S-Tags.htm#search-S130

     

     

    Your search for "S130" returned 0 result(s)

    "This makes me sad"

     

    I  LOLed.

  • Brian Mucha:

    "This makes me sad"

     

    I  LOLed.

    Kent is passing along Bo's request for more documentation on it.

     

    However, this tag is probably not well documented for a couple reasons:

    1) It is complicated so not that many people even attempt to use it

    2) It is mainly used by engineering though over the last 5 years some of the more advanced web dev folks in our services team have been using it more often.

    3) It can bring your site or a server down under a special set of circumstances. I've seen it happen by accident when one of our web developers who was making something for a client's campaign.

     

    He was trying to do something a little nutty so if you are just using it for simple math and items like Chris mentioned you should have no problems.

     

    Ken

  • Ken Cantu:

    Kent is passing along Bo's request for more documentation on it.

     

    However, this tag is probably not well documented for a couple reasons:

    1) It is complicated so not that many people even attempt to use it

    2) It is mainly used by engineering though over the last 5 years some of the more advanced web dev folks in our services team have been using it more often.

    3) It can bring your site or a server down under a special set of circumstances. I've seen it happen by accident when one of our web developers who was making something for a client's campaign.

     

    He was trying to do something a little nutty so if you are just using it for simple math and items like Chris mentioned you should have no problems.

     

    Ken

    I'm making a thermometer for a TeamRaiser coaching email using the [[S48:1520:smileytongue:ct-of-goal]] tag .

     

    Here's what I want:

     

     

     

    But it turns out that if pct-of-goal is 0, the thermo doesn't render correctly in most mail clients. Additionally it can return values higher than 100 when the goal as been exceeded, which also messes things up.

     

    I spent quite a while fooling with E130 and multiple ternarys, trying to keep the value between 1 and 99. It turned out to be so simple I thought I'd post it.

     

    [[E130:[[S48:1520:smileytongue:ct-of-goal]] 1 max 99 min]]

     

    Here's what it does:

     

    [[S48:1520:smileytongue:ct-of-goal]] 1 max

    Take the percent of goal and compare with 1 and return the higher number. This eliminates 0 values.

     

    (RESULT) 99 min

    Take the result of the above and compare with 99 and return the lower number. This eliminates 100 and higher values.

     

    So here's my final code:

     


    <table width="100%" border="1" cellspacing="0" cellpadding="0" style="border-collapse: collapse;">
    <tr>
    <td style="background-color: #026BBB; width:[[E130:[[S48:1520:smileytongue:ct-of-goal]] 1 max 100 min]]%;"><img alt="" style="display: block;" src="http://[[S29:smileyvery-happy:OMAIN]]/_resources-email/_common/images/nothing.gif" border="0" width="1" height="10" /></td>
    <td style="background-color: #FFFFFF;"></td>
    </tr>
    </table>

     

    S130 / Polish Notation - so cool.

  • Kent Gilliam
    Kent Gilliam Blackbaud Employee
    Ancient Membership 2500 Comments 100 Likes Name Dropper
    Brian Mucha:

    I'm making a thermometer for a TeamRaiser coaching email using the [[S48:1520:smileytongue:ct-of-goal]] tag .

     

    Here's what I want:

     

     

     

    But it turns out that if pct-of-goal is 0, the thermo doesn't render correctly in most mail clients. Additionally it can return values higher than 100 when the goal as been exceeded, which also messes things up.

     

    I spent quite a while fooling with E130 and multiple ternarys, trying to keep the value between 1 and 99. It turned out to be so simple I thought I'd post it.

     

    [[E130:[[S48:1520:smileytongue:ct-of-goal]] 1 max 99 min]]

     

    Here's what it does:

     

    [[S48:1520:smileytongue:ct-of-goal]] 1 max

    Take the percent of goal and compare with 1 and return the higher number. This eliminates 0 values.

     

    (RESULT) 99 min

    Take the result of the above and compare with 99 and return the lower number. This eliminates 100 and higher values.

     

    So here's my final code:

     


    <table width="100%" border="1" cellspacing="0" cellpadding="0" style="border-collapse: collapse;">
    <tr>
    <td style="background-color: #026BBB; width:[[E130:[[S48:1520:smileytongue:ct-of-goal]] 1 max 100 min]]%;"><img alt="" style="display: block;" src="http://[[S29:smileyvery-happy:OMAIN]]/_resources-email/_common/images/nothing.gif" border="0" width="1" height="10" /></td>
    <td style="background-color: #FFFFFF;"></td>
    </tr>
    </table>

     

    S130 / Polish Notation - so cool.

    More "gold" from Mr. Mucha!!!!!! Now how about that tree that grows money idea? Can you figure that one out? lol Happy holidays my friend!

     

    Kent

  • Kent Gilliam
    Kent Gilliam Blackbaud Employee
    Ancient Membership 2500 Comments 100 Likes Name Dropper
    Kent Gilliam:

    More "gold" from Mr. Mucha!!!!!! Now how about that tree that grows money idea? Can you figure that one out? lol Happy holidays my friend!

     

    Kent

    Hey Brian,

     

    Already have some requests for a screenshot of this in action. Any way you could post a screenshot of your email?

     

    Kent

  • Kent Gilliam:

    Hey Brian,

     

    Already have some requests for a screenshot of this in action. Any way you could post a screenshot of your email?

     

    Kent

    https://litmus.com/pub/3616ee0

     

    The attachment still shows an old bug with the Days Left value, but it has the Personal Page Not Updated alert and a bunch of custom achievement badges I created, which do not appear in the Litmus test.

  • REPOST WITH S-TAGS FIXED


    I'm making a thermometer for a TeamRaiser coaching email using the [[S48:1520:pct-of-goal]] tag .

     

    Here's what I want:

     

     

     

    But it turns out that if pct-of-goal is 0, the thermo doesn't render correctly in most mail clients. Additionally it can return values higher than 100 when the goal as been exceeded, which also messes things up.

     

    I spent quite a while fooling with E130 and multiple ternarys, trying to keep the value between 1 and 99. It turned out to be so simple I thought I'd post it.

     

    [[E130:[[S48:1520:pct-of-goal]] 1 max 99 min]]

     

    Here's what it does:

     

    [[S48:1520:pct-of-goal]] 1 max

    Take the percent of goal and compare with 1 and return the higher number. This eliminates 0 values.

     

    (RESULT) 99 min

    Take the result of the above and compare with 99 and return the lower number. This eliminates 100 and higher values.

     

    So here's my final code:

     


    <table width="100%" border="1" cellspacing="0" cellpadding="0" style="border-collapse: collapse;">
    <tr>
    <td style="background-color: #026BBB; width:[[E130:[[S48:1520:pct-of-goal]] 1 max 100 min]]%;"><img alt="" style="display: block;" src="http://[[S29:DOMAIN]]/_resources-email/_common/images/nothing.gif" border="0" width="1" height="10" /></td>
    <td style="background-color: #FFFFFF;"></td>
    </tr>
    </table>

     

    S130 / Polish Notation - so cool.

Categories