Understanding Liquid markup and Zendesk Support

Return to top
Have more questions? Submit a request

100 Comments

  • Jason Littrell

    Hi Jennifer,

    This seems like an easy enough problem, but it's actually somewhat complicated.

    For starters, capturing the "ticket.tags" placeholder is unnecessary. Capture is only used for strings and the "ticket.tags" placeholder is already a string of tags separated by spaces. If you test this after your "endcapture" tag,

    {{tags}}
    {{ticket.tags}}

    you'll see they are the same. If you want to put the tags in an array, instead, use the "assign" tag:

    {% assign tags = ticket.tags | split: " " %}

    This splits the "ticket.tags" string at each space and puts them in your "tags" array.

    Another problem is that your "case" statement is using "tag" instead of your "tags" variable, but even if you change it, you'll still be trying to evaluate the entire string. If your tags contain "amz" and "test", for example, your string will be "amz test" and "when 'amz'" will evaluate as false.

    You can use the "assign" method from above and loop through it with a "for" statement. Based on your example, it would look something like this:

    {% assign tags = ticket.tags | split: " " %}{% for tag in tags %}{% case tag %}
    {% when 'amz' %}
    you will be refunded back to your amazon account
    {% when 'paypal' %}
    you will be refunded back to your paypal
    {% else %}
    you have not been charged
    {% endcase %}{% endfor %}

    Note: in this example, "case tag" works because we assigned the item name in the "for" loop ("for tag in tags"), and the "case" statement is evaluating an individual tag instead of the whole array.

    There are some problems with this approach, though. First, since you are evaluating each tag individually, every tag that is not "amz" or "paypal" will print "you have not been charged". Similarly, if your tags contain "amz" and "paypal", it will print both of the first two statements.

    You can remove the "else" statement from the "for" loop, but then you would need to find a way to fallback to your default string if the "tags" array doesn't contain "amz" or "paypal". One way to do that would be to capture your text as a string variable, then evaluate it after the "for" loop. For example:

    {% assign tags = ticket.tags | split: " " %}
    {% assign refund = "you have not been charged" %}
    {% for tag in tags %}{% case tag %}
    {% when 'amz' %}
    {% assign refund = 'you will be refunded back to your amazon account' %}
    {% when 'paypal' %}
    {% assign refund = 'you will be refunded back to your paypal' %}
    {% endcase %}{% endfor %}
    {{refund}}

    Note: with this code, if your array contains both "amz" and "paypal", your text string will be overwritten by whatever is later in the array.

    The easiest method, though, would be to run an "if" statement on your "tags" array:

    {% assign tags = ticket.tags | split: " " %}
    {% if tags contains 'amz' %}
    you will be refunded back to your amazon account
    {% elsif tags contains 'paypal' %}
    you will be refunded back to your paypal
    {% else %}
    you have not been charged
    {% endif %}

    This will check to see if any items in the array match "amz", then "paypal", then return your default text if both are false. If your array contains both tags, "amz" will return as true first and break the loop.

    You can also forgo the array and just run an "if" statement on the "ticket.tags" string:

    {% if ticket.tags contains 'amz' %}
    you will be refunded back to your amazon account
    {% elsif ticket.tags contains 'paypal' %}
    you will be refunded back to your paypal
    {% else %}
    you have not been charged
    {% endif %}

    The problem here is that any tags that contain "amz" or "paypal" (for example, "notamz" or "notpaypal") will return as true. If you're confident that your tags are unique, though, this is a viable option.

    You're biggest hurdle at this point might be making sure that tickets that have the "amz" tag cannot have the "paypal" tag, and vice versa. Otherwise, make sure that whichever text string you want to default to when both are present is listed first in your "if" statement.

    Hope this helps. Let me know if you have any questions.

    6
  • Jason Littrell

    @Sarah The problem is that the ticket.tags placeholder produces a string so 'contains' will look for any part of the string. To get around this, you can convert it to an array like this:

    {% assign tags = ticket.tags | split: ' ' %}

    Then you would just replace 'ticket.tags' with 'tags' in your first four examples above. For example:

    {% if tags contains 'sat' %}...

    Using 'contains' on an array checks the array for the value you specify, but will not search within individual values. Try it with 'sat' and 'satisfaction' tags, then again without the 'sat' tag and you should get different results.

    3
  • Sebastiaan Wijchers
    Community Moderator

    Hello Daniël,

    As far as I know that's not possible. Did you consider using 'dynamic content' to achieve what you're after? I think that will do the job in some scenarios.

    With kind regards,

    Sebastiaan
    Sparkly ⭐

    2
  • Jason Littrell

    @Sam You can use an HTTP target to accomplish this (see here and here for inspiration). Your best bet, though, is to accomplish this with a trigger. Here's a barebones example of how you could set one up:

    2
  • Jason Littrell

    @Oliver  In your first block of code, the most likely problem is that your "newtag" variable is being overwritten by subsequent tags. Essentially, the last tag that is evaluated by the for loop will determine what the "newtag" variable is set to. To get around this, add a {% break %} tag after assigning "newtag" to "YES" to exit out of the for loop.

    Regarding your second attempt, using "tags contains" is much simpler than the for loop you created, but you have to be careful with how you code multiple boolean conditions. In your case, you have two conditions:

         tags contains 'tag_1'

    and

         'tag_2'

    Liquid is trying to evaluate the string 'tag_2' by itself and it considers any strings to be truthy (more info here). To fix this, you have to be explicit about what you do with the 'tag_2' string. This code should do what you want:

    {% assign tags = ticket.tags | split: ' ' %}
    {% if tags contains 'tag_1' or tags contains 'tag_2' %}{% assign newtag = 'YES' %}{% else %}{% assign newtag = 'NO' %}{% endif %}

    Hope this helps!

    2
  • Becca
    Zendesk team member

    Hi Michael - 

    I did some research and brainstorming on this and unfortunately I am thinking this is likely not directly possible. Some type of value is always going to be required in the name field for a user and this value, if a single string will be considered the first name by the name placeholders. As a result, if the name is unknown and Zendesk pulls in the beginning of the email address, this would still be considered the first name value meaning the {{ticket.requester.first_name}}  placeholder would always see some type of value. 

    Once option I did think maybe promising is implementing some type of regex in your Liquid on the value of the first name to determine if it matches the beginning to the ticket requester's email address. However this would have downsides as in some cases the email could be the same as their first name. 

    1
  • Jason Littrell

    @Sarah That's correct. You'll need to assign the "tags" variable first, but also make sure that you're splitting with a space and not just two single quotes (i.e. ' ' and not ''). The latter will split on every character in the tags string.

    I'll have to do some testing, but one thing I noticed in your second question is that the "gmat" if condition starts with an incorrect single quote. It's not clearly visible with this site's font, so this code block might make it easier to see:

    {% if ticket.tags contains ‘gmat' %}

    Liquid doesn't play nice with the smart-style quotes, so replacing it with a standard single quote might make that portion of the code work. 

    1
  • Anais

    Hi there. I'm using Liquid in my macro, but I can't figure out how to check if a chekbox is checked.

    I tried things like fieldID[checked]  or fieldID.checked : {% if ticket.ticket_field_360016124819[checked] %}

    Thanks in advance for your help !

    1
  • Chris Swinney

    Ahhhhhh, rookie mistake. In my hackery, I managed to delete a trailing `%` from the opening `if` statement. Looks like `capture` does the trick.

    1
  • Dan Ross
    Community Moderator

    Hey Anais,

    As far as I know, Liquid can't check field states that way. In this case, try making sure your checkbox field applies a tag when checked and then test for the presence of that tag. If it's there, the field is checked, otherwise it's not.

    Something like this might help get you started.

    {% if ticket.tags contains ‘checkbox_tag' %}
    1
  • Ilya Dovidovskii

    Can you guys add this functionality to Agent signature? I tried to implement the {% ticket.requester.language %}... in Admin>Settings>Agent>Signature but it always returns the {% else %} section.

    1
  • Anais

    Dan Ross

    Thank you so much Dan for your prompt assistance.

    Indeed, it works with the tag.

    You saved my day !

     

    1
  • Joshua Atkin

    I don't believe this works in signatures, is that true? in essence I would like to build a custom signature depending on which organization writes to me and I could do that with Liquid

    1
  • Jason Littrell

    @Jack You can use the "/api/v2/locales/public.json" endpoint to pull up the data. For Bosnian its:

    "url": "https://yapstone.zendesk.com/api/v2/locales/bs.json",
    "id": 1008,
    "locale": "bs",
    "name": "Bosnian",
    "native_name": "bosanski",
    "presentation_name": "Bosnian - bosanski",
    "rtl": false,
    "created_at": "2010-01-11T11:54:03Z",
    "updated_at": "2016-10-27T00:09:14Z",
    "default": false

    And Bulgarian shows:

    "url": "https://yapstone.zendesk.com/api/v2/locales/bg.json",
    "id": 94,
    "locale": "bg",
    "name": "Bulgarian",
    "native_name": "български",
    "presentation_name": "Bulgarian - български",
    "rtl": false,
    "created_at": "2009-07-21T10:51:33Z",
    "updated_at": "2017-02-18T17:32:33Z",
    "default": false

    The "name" value is returned when using the {{ticket.requester.language}} placeholder, while the "locale" value will be returned for {{ticket.requester.locale}}.

    *Edit: for just the languages that your Zendesk instance supports, you can use "/api/v2/locales.json".

    1
  • Chris Swinney

    FWIW, I have tried a bunch of different syntax changes of the `assign` line, such as:

    {% assign issue = tag | remove "issue_" %}
    {% assign issue = tag %}
    {% assign issue = {{ tag }} %} 

    (with the last two I would have manipulated the variable `issues` later)

    But with not much luck so far.

    I even tried:

    {% capture issue %}{{ tag | remove: "issue_" }}{% endcapture %}

    But this result in a syntax error as Zen doesn't seem to understand the `{% endcapture %}` tag

    0
  • Tsvetan

    Hi guys,

    I need help. I am struggling with the following case. I would like to make a check about signature in the Brands>>Agent signature section. Currently the check is as follows - if it's not specific agent then enter empty space, otherwise enter the predefined signature. Here is the code. So far is working nice, however I want now to extend the logic, where even if it's that agent, to additionally check for specific ticket.tag and if it's there, to enter again an empty space.

    I have tried with almost everything, but it seems I cannot make it working. Something which makes me to think that this cannot happen is that, that from the Agent signature section I cannot collect the ticket.tags. Probably the ticket is still not created at that stage. Where the Notification triggers collect and shows the ticket.tags.

    One of the examples:

     

    {% assign tags = ticket.tags | split: " " %}
    {% for tag in tags %}{% if tag == 'testtag' %}
    {% assign x = true %}
    {% endif %}{% endfor %}

    {% if agent.email != 'agent@email.com' and x = true %}
    left blank
    {% esle %}
    My signature
    {{current_user}}
    {{current_user.notes}}
    {{% endif %}}

     

    I have tried with capture and many different things, but couldn't make it working. Any assistance or advises will be much appreciated.

    0
  • Todd Meyer

    I set up an IF/ELSE condition in a macro and noticed several lines of whitespace being generated when the macro is invoked.  

    Looking at the Liquid documentation here: https://shopify.github.io/liquid/basics/whitespace/ they have a way to eliminate the whitespace, but I can't get Zendesk to accept the syntax.

    It keeps telling me:

    • A template placeholder is in an invalid format: Liquid syntax error: Tag '{%- if ticket.description contains 'Banana' -%}' was not properly terminated with regexp: /\%\}/

    Is this a bug in ZD? Do they need to update their installation to account for this? Is there another way to remove all the whitespace that gets generated in the meantime?

    Thanks in advance 😀

    0
  • Jacob J Christensen
    Community Moderator

    Hi Brendan, maybe this will help you:
    Send out different notification messages using liquid.

     

    0
  • Jameel Boonzaaier

    Hi Brett

     

    From what i can see its blank

     

    0
  • Stuart Warren

    Is it possible to use liquid markup in Brands signatures? I have set up a brand signature that has markdown to display a hosted image; works great for email but when an SMS is sent there are issues. I have tried adding the following into the brand signature section and it seems to always return else. 

    {% assign tags = ticket.tags | split: " " %}
    {% if tags contains 'outbound_text' %}

    XYZ Support
    P: 1300 000 000
    E: support@xyz.com

    {% else %}

    **{{agent.name}}**
    {{agent.signature}}
    {{agent.phone}}
    support@xyz.com
    [xyz.com](http://xyz.com)

    ![xyz](https://xyz.com/assets/folder/logo.png)

    {% endif %}

    Goal: When an SMS is sent to a customer via a trigger, the brand signature returns the plain text "XYZ Support
    P: 1300 000 000
    E: support@xyz.com".

    0
  • Fernando Duarte

    @Ajay

     

    Liquid is used to update the formatting of text, not fields

    0
  • Brett Bowser
    Zendesk Community Team

    Hey Jameel,

    Can you provide a screenshot of the company name you're referring to in the email?

    That may help give a better understanding of what you're trying to remove.

    Thanks!

    0
  • Raman Kalia

    Dear Simon,

    Thanks for writing back!

    I do not want to search URLs. Let me rephrase my concern below.

    Scenario 1

    Criteria word - 'Transport'.

    Condition - If comment from the user contains this word, e.g. 'When is my transport getting arranged' or 'what are the timings of monrning transport'.

    Result -

    'Dear user you may also like to explore information on below link with respect to your transport related query'
    URL Link - https://mydomain.com/TransprotQueries (this URL is hardcoded into my script)


    Scenario 2

    Criteria words - 'Transport' and 'Fee'.

    Condition -
    (For 'Transport') If comment from the user contains this word, e.g. 'When is my transport getting arranged' or 'what are the timings of morning transport'.
    (For 'Fee') If comment from the user contains word 'fee', e.g. 'when can I come to submit the fee' or 'What are the free subsidies available'.

    Result -

    'Dear user you may also like to explore information on below link with respect to your transport related query'
    URL Link - https://mydomain.com/TransprotQueries.html (this URL is hard-coded into my script)

    'Dear user you may also like to explore information on below link with respect to your fee related query'
    URL Link - https://mydomain.com/FeeQueries.html (this URL is hard-coded into my script)

    Both above URLs will be hard coded in the script.

    I would like to call as many up to 5 such URL based on 5 different words if they come altogether in same comment from the user.

    Thanks

    Raman

    0
  • Donald Cornel

    Hi Raman Kalia,

    Sorry I missed to respond on your comment.

    I just have follow up question on that.

    How can I copy the value of that field to another field without me manually typing the value?

    Like {{ticket.field1}} = {{ticket.field2}}

    0
  • Brett Bowser
    Zendesk Community Team

    Hey Jameel,

    This looks like the optional name that is showing up next to your support address. If you navigate to Admin>Channels>Email and select Edit next to your support address, do you see the company name showing in the Name (optional) field?

    Let me know!

    0
  • Daniël Nieuwendijk
    Did you already try it out?

    Andreas Schuster Yes I have. And I can say it works pretty well! I find that I need to pay a bit more attention, but as long as you know what you're doing, test what you did, and don't apply it willy-nilly, it works. At least for me, it does.

    0
  • Daniël Nieuwendijk

    Is it possible to (conditionally) include another macro into the current macro, using Liquid?

    The use case is such, that we re-use the same building blocks of text in many different macros, but they can't be combined into one macro using if statements, because there's a human decision needed.

    If these texts need to be updated, they need to be updated in many macros. It would save work and prevent omissions if I only needed to update them in one place.

    So I would like to be able to do something along the lines of:

    {% if varXYZ == 1 %}
    {{ macros.macroname123.comment_value }}
    {% else %}
    {{ macros.macroname456.comment_value }}
    {% endif %}
    0
  • Lars

    Hey everybody!

    We have two different groups in our Zendesk support. I am currently trying to implement dynamic sentences into a macro. Those sentences are supposed to be different for the two groups
    If a ticket is in group 1 I want to add website A,
    if a ticket is in group 2 I want to add website B.

    I tried this, but it did not work. Does anyone have ideas? :-)

    {% if ticket.group.name == '1‘ %}
    Website A
    {% elsif ticket.group.name == '2‘ %}
    Website B
    {% endif %}

    The output I get is this error: "Liquid error: Unknown operator href="

    Also, I was not even able to get a code from https://github.com/Shopify/liquid/wiki/Liquid-for-Designers <https://github.com/Shopify/liquid/wiki/Liquid-for-Designers> to work.

    {% if user.name == 'tobi' %}
    Hello tobi
    {% elsif user.name == 'bob' %}
    Hello bob
    {% endif %}

    That code did not display anything. Even when I changed the names to the names that were actually in the ticket.

    Thank you so much!

    0
  • Oliver Knigge

    Finally, this helps! :)

    Now the conditions are working as expected.

    Thank you so much Jason!

    0
  • Jacob J Christensen
    Community Moderator

    Hi Jack,

    I can't validate it myself, but (if those languages are supported in Liquid Markup) I believe that it should be:

    Bosanski

    and

    Български

     

     

    0

Please sign in to leave a comment.

Powered by Zendesk