14 Replies Latest reply on Feb 22, 2018 5:15 PM by Matthew Varone

    How do I modify the date format for a token using Velocity Script?

    Laura Kimball

      Hello Community,

       

      We'd like to be able to change the date format for an expiration date token (see below) from appearing in an email as 2018-04-12 to April 12, 2018. How would I set up the Velocity Script to do so?

       

      {{lead.Expiration Date:default=edit me}}

       

      Thank you,

       

      Laura Kimball

        • Re: How do I modify the date format for a token using Velocity Script?
          Sanford Whiteman
          #set( $dateOptions = {
            "formats" : {
              "userin" : "yyyy-MM-dd",
              "userout" : "MMMM d, yyyy"
            },
            "timezones" : {
              "userin" : "America/New_York",
              "userout" : "America/New_York"
            },
            "locale" : $date.getLocale()
          } )
          #set( $expirationDatelike = $lead.ExpirationDate )
          #set( $expirationDate = $convert.parseDate(
            $expirationDatelike,
            $dateOptions.formats.userin,
            $dateOptions.locale,
            $date.getTimeZone().getTimeZone($dateOptions.timezones.userin)
          ) )
          #set( $expirationDate_formatted = $date.format(
            $dateOptions.formats.userout,
            $expirationDate,
            $dateOptions.locale,
            $date.getTimeZone().getTimeZone($dateOptions.timezones.userout)
          ) )
          ${expirationDate_formatted}
          

           

          Note the very important inclusion of time zones (set the userin and userout time zone strings according to your tz).

           

          You'll see a lot of examples (frankly, any examples that weren't originally contributed by yours truly) that are broken because they are timezone-unaware.  Those examples may seem simpler, but they're broken.

          2 of 2 people found this helpful
            • Re: How do I modify the date format for a token using Velocity Script?
              Laura Kimball

              AWESOME! Thank you so much Sanford!

               

              For a non-programmer like myself, do you have any suggestions for how to approach the development of these scripts? In other words, is there a "method to the madness"? For example, for the lead.DBCBalance script you helped me with earlier, the script was very simple--just 1 line, whereas with this particular script there are 25 lines of code...What is the difference?

               

              Thank you,

               

              Laura

                • Re: How do I modify the date format for a token using Velocity Script?
                  Sanford Whiteman

                  Well, they're doing very different things, since the other one is just formatting an existing string and this one is actually creating Date objects from strings (which is a surprisingly sensitive process in any language) and then outputting them as strings.

                   

                  Because of the number/length of the function arguments, I broke up the parseDate() and format() calls into multiple lines with line breaks -- so each of those #set lines could technically be on one line, but then they'd be far harder to read.

                   

                  It's not really about lines of code (LoC), though. Yes, you do hear programmers bragging about their LoC (in both directions -- sometime we say, "I could do that in 3 lines" while in other contexts we say, "We have a mature codebase of 100,000 LoC, so don't tell us changes are simple.").

                   

                  But the key is writing the shortest amount of code that is readable and maintainable -- and no shorter! That means you add line breaks as necessary for readability, and declare variables (like my $dateOptions), instead of hard-coding values, for easier reconfiguration over time.  This may add lines but your code is better for it. Where you save "lines" is by using time-tested functions to do stuff, instead of trying to write your own. Like you don't try to write your own date parser when Velocity already has one that works.

                   

                  Overall, though, Velocity is a programming language, and I can't give non-programmer-y pointers for how to learn it. I love Velo (well, maybe that's strong, I enjoy learning its quirks and the power it brings to Marketo) but I am a programmer by trade, so...

                  1 of 1 people found this helpful
                    • Re: How do I modify the date format for a token using Velocity Script?
                      Laura Kimball

                      Well, they're doing very different things, since the other one is just formatting an existing string and this one is actually creating Date objects from strings (which is a surprisingly sensitive process in any language) and then outputting them as strings.

                      Can you please explain what you mean by "creating Date objects from strings"? What are the strings that comprise the Expiration Date token and what are the date objects they become?

                       

                      But the key is writing the shortest amount of code that is readable and maintainable -- and no shorter! That means you add line breaks as necessary for readability, and declare variables (like my $dateOptions), instead of hard-coding values, for easier reconfiguration over time.  This may add lines but your code is better for it. Where you save "lines" is by using time-tested functions to do stuff, instead of trying to write your own. Like you don't try to write your own date parser when Velocity already has one that works.

                      Is the variable my $dateOptions an "arbitrary" variable or is it one that is used often in velocity scripting? That is, is it a "standard" variable (for lack of a better term) or was it created for a specific purpose? If standard, are there other standard variables?

                      Overall, though, Velocity is a programming language, and I can't give non-programmer-y pointers for how to learn it. I love Velo (well, maybe that's strong, I enjoy learning its quirks and the power it brings to Marketo) but I am a programmer by trade, so...

                      Where would be a good place to start to get a better grasp of programming in general and how Velocity functions as a programming language?

                       

                      Thanks again for your feedback!

                       

                      Laura

                        • Re: How do I modify the date format for a token using Velocity Script?
                          Phillip Wild

                          Hi Laura

                           

                          Reading this, I can totally empathise. I might be a little further along the line than you, so I'd be happy to give you some help (including some docs I've created myself) which might help to explain some of the above. Send me a PM with your email if you're interested.

                           

                          I must say that pretty much all I've learnt has been due to two main factors: a lot of trial and error, and Sanford's work. Here's a blog post which will help to explain a question you have above: http://blog.teknkl.com/marketo-vtl-strings-all-the-way-down/

                            • Re: How do I modify the date format for a token using Velocity Script?
                              Phillip Wild

                              PS - I had the exact same date formatting problem Sanford Whiteman - so this question and post is very timely! I wasn't inputting timezones. Your code is very clean as usual - thanks so much. I won't be making that mistake again...

                                • Re: How do I modify the date format for a token using Velocity Script?
                                  Phillip Wild

                                  Hmm I spoke slightly too soon. When I input the date "04/17/2017", I keep getting as the output January 17, 2017 instead of April 17, 2017. Why?

                                   

                                  My code below. The only changes I've made are around the index I'm substituting in, and the "user in" formatting.

                                   

                                  ## get the size of the list

                                  #set ($listlength = ${abandonedCart_cList.size()})

                                  ## remove one from the size of the list to reference the right object in the array (arrays start at zero, not 1)

                                  #set( $lastIndex = $math.sub($listlength,1) )

                                  ## convert the Service Start Date string to a date

                                  #set( $dateOptions = { 

                                    "formats" : { 

                                      "userin" : "mm/dd/yyyy", 

                                      "userout" : "MMMM d, yyyy" 

                                    }, 

                                    "timezones" : { 

                                      "userin" : "America/New_York", 

                                      "userout" : "America/New_York" 

                                    }, 

                                    "locale" : $date.getLocale() 

                                  } ) 

                                  #set( $ServiceStartDatelike = $abandonedCart_cList.get($lastIndex).serviceStartDate ) 

                                  #set( $ServiceStartDate = $convert.parseDate( 

                                    $ServiceStartDatelike, 

                                    $dateOptions.formats.userin, 

                                    $dateOptions.locale, 

                                    $date.getTimeZone().getTimeZone($dateOptions.timezones.userin) 

                                  ) )

                                  ## convert the date to a different format

                                  #set( $ServiceStartDate_formatted = $date.format( 

                                    $dateOptions.formats.userout, 

                                    $ServiceStartDate, 

                                    $dateOptions.locale, 

                                    $date.getTimeZone().getTimeZone($dateOptions.timezones.userout) 

                                  ) ) 

                                  ${ServiceStartDate_formatted} 

                                   

                                  Thanks, any help appreciated.

                                • Re: How do I modify the date format for a token using Velocity Script?
                                  Laura Kimball

                                  Thanks Phillip! It's nice to know I'm not alone in this area. I really want to get to the point where I am more autonomous in being able to tackle VS (and other technical areas related to Marketo)I'm not looking to be a VS guru (lol), but would at least like to be able to make strides in those areas and be more confident in how to execute on setting up VS code if  my company needs something done right away.

                                   

                                  Thanks for offering to share your docs with me . I'll PM you my email address in a few minutes.

                                   

                                  Again, I really appreciate your feedback and offer to help!

                                   

                                  Laura

                                  • Re: How do I modify the date format for a token using Velocity Script?
                                    Laura Kimball

                                    Hi Phillip,

                                     

                                    I don't see a way to PM you through Marketo...Is there something you see that I don't?

                                     

                                    Thank you,

                                     

                                    Laura

                                  • Re: How do I modify the date format for a token using Velocity Script?
                                    Sanford Whiteman

                                    Can you please explain what you mean by "creating Date objects from strings"? What are the strings that comprise the Expiration Date token and what are the date objects they become?

                                    Your Expiration Date field may be set up as a Date type in Marketo, but when it's made visible in Velocity (as $lead.ExpirationDate or $lead.expirationDate or whatever you see when you choose it from the tree) it's merely a "date-like string" (that's a why I use $expirationDatelike as the variable name).

                                     

                                    Essentially, you get the display version of what may or may not originally have been a Date variable (it could've been a custom String field in Marketo and it would look the same in Velocity).

                                     

                                    The string value "2017-07-01" has no built-in date-like qualities: you can't reformat it as 'MMMM dd, yyyy', you can't add or subtract days from it, you can't set its timezone, etc. So it's not actually "a date" from a computer's standpoint, it only looks kind of like one to us humans.

                                     

                                    But you can parse it into an intelligent Date object, since it follows one of well-known formats ('yyyy-MM-dd'). Once it's a real date ($expirationDate) you get the special date methods for reformatting, time calculation, etc.

                                     

                                    Date fields being presented in Marketo's Velocity implementation as strings is a Marketo thing, not a Velocity thing.  Velocity as a language was developed far outside of Marketo, and it does support Date fields directly. So $lead.expirationDate could've already been a Date, technically speaking, but Marketo chose not to do it that way. Important to note the distinction, since when you're learning Velocity almost 100% of the examples on the net are not Marketo-specific. (My blog is a notable exception : http://blog.teknkl.com/tag/velocity.)

                                     

                                    Is the variable my $dateOptions an "arbitrary" variable or is it one that is used often in velocity scripting? That is, is it a "standard" variable (for lack of a better term) or was it created for a specific purpose? If standard, are there other standard variables?

                                    Completely custom variable. Any $var that gets #set in a script token is not built-in or standard.

                                     

                                    There are several standard objects ("tools") with a range of built-in methods: Apache Velocity Tools - Generic Tools

                                     

                                    But you also get access to a far wider, almost mind-blowing range of Java methods, depending on what kind of data you're dealing with. Velocity overlaps with Java -- it's neither a superset nor merely a subset of Java -- but can dip into some hugely powerful parts of the Java language as well as its own Velo-only functionality.

                                     

                                    Where would be a good place to start to get a better grasp of programming in general and how Velocity functions as a programming language?

                                    I love/hate these questions!

                                     

                                    I'd def'ly point you to my blog, where my Velocity posts and stuff like the Code Anatomy series (http://blog.teknkl.com/tag/code-anatomy) try to take a bottom-up approach to how to build functions for some common needs. Since I work mostly in martech and its environs, the cases are likely to be more familiar than on a general programming blog. (I have a few Code Anatomy posts in Drafts that I really need to get out.)

                                     

                                    I'm also really happy to chat for a bit about going in a mar-technical direction. Just follow me here and then we can DM each other and set it up. I have periodic apprentice-type sessions with a few people on the Community and am happy to take on another.