TracCloud: Twig: Difference between revisions

From Redrock Wiki

No edit summary
No edit summary
 
(30 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{TracCloudGuideTabs}}
{{TracCloudGuideTabs}}
<div class="tcWidgetPage">
<div class="tcWidgetPage">
<div class="categoryWide">
<div class="categoryDynamic">
{{TracCloudGuideProfileTOC}}
{{TracCloudGuideProfileTOC}}
</div>
</div>
<big><b>Formatting Text in TracCloud with Twig and HTML</b></big><br><br>
<div class="pageTitle">TracCloud Twig Guide</div>
Many text fields throughout TracCloud support Twig and HTML, giving you greater control in determining what data is displayed to your users based on the context of appointments, visits, and more, as well as formatting that data to be as clear as possible.<br><br>
 
Many text fields throughout TracCloud support Twig and HTML, giving you greater control in determining what data is displayed to your students, staff, and faculty based on the context of appointments, visits, and more, as well as formatting that data to be as clear as possible.


<b>Twig</b> will be the primary focus of this article. Twig is a template engine that serves two primary purposes in TracCloud:
<b>Twig</b> will be the primary focus of this article. Twig is a template engine that serves two primary purposes in TracCloud:
Line 13: Line 14:


* <b>2. Add logic to your text</b>
* <b>2. Add logic to your text</b>
::Modify the email or message based on why it was sent. Add an extra paragraph if X center was selected, send a follow-up email after a visit if the student chose Y, prevent an email from being sent on a SAGE referral if Z recommendation was checked, and much more. Rather than creating a generic email for any context, create an email that formats itself to match the current context.<br><br>
::Modify the email or message based on why it was sent. Add an extra paragraph if Reason X was selected, send a follow-up email after a visit if the student chose Y, prevent an email from being sent on a SAGE referral if Z recommendation was checked, and much more. Rather than creating a generic email for any context, create a dynamic email that changes to match your needs.<br><br>


Twig (and HTML) are supported in [[TracCloudGuideProfilePrefsEmails|profile emails]], [[TracCloud:_Welcome_Messages|welcome messages]], [[TracCloud:_Email_Templates|email templates]], [[TracCloudGuideProfilePrefsScheduleDisplay|appointment display]], and more. Most of the examples listed in this article are for appointment emails or SAGE referrals, but the same concepts apply in all other supported fields. It's also worth keeping in mind that Twig exists outside of TracCloud, and there are many resources online for how you can utilize it that will also work here. This guide likely covers everything you will need, but it doesn't cover everything Twig is capable of.<br><br>
Twig (and HTML) are supported in [[TracCloudGuideProfilePrefsEmails|profile emails]], [[TracCloud:_Welcome_Messages|welcome messages]], [[TracCloud:_Email_Templates|email templates]], [[TracCloudGuideProfilePrefsScheduleDisplay|appointment display]], and more. Most of the examples listed in this article are for appointment emails or SAGE referrals, but the same concepts apply in all other supported fields. It's also worth keeping in mind that Twig exists outside of TracCloud and there are many resources online for how you can utilize it that will also work here (such as [https://twig.symfony.com/doc/3.x/ Symfony]). This guide likely covers everything you will need, but it doesn't cover everything that Twig is capable of.<br><br>


<b>HTML</b> will also be used throughout this article, but without much explanation as it's more ubiquitous than Twig. There are many excellent resources online explaining how to use this markup language, such as [https://www.w3schools.com/html/html_styles.asp W3Schools]. HTML is used to adjust font sizes and colors, embed images and videos, and more.
<b>HTML</b> will also be used sparingly throughout this article, but without much explanation as it's more ubiquitous than Twig. There are many excellent resources online explaining how to use this markup language, such as [https://www.w3schools.com/html/html_styles.asp W3Schools]. HTML is used to adjust font sizes and colors, embed images and videos, and more.
<hr>
<!-------------------------------------------- Tags-------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><b>What are Twig tags?</b></big></div><div class="mw-collapsible mw-collapsed"><br><br>
Twig tags can be used to pull data from various TracCloud fields to be included in emails and upcoming appointments. Many of the Twig examples in this chapter will be using these tags, whether they’re used as part of a Twig command or just offhandedly included in an unrelated part of the email. A list of tags can be found at the bottom of this chapter (and within the TracCloud menu), but for a basic primer on how these tags can be used in isolation, here’s an example of a confirmation email.


<syntaxhighlight style="border: 1px dashed black" lang="twig" line>
==Part 1. Syntax, Terminology, and Essential Knowledge==
Hello, {{Student.First_Name}}
When reading the wiki or talking to support, you will often see fields like <i>Student.First_Name</i> or <i>Courses.Subject</i> referred to as "Twig tags." To use another term, these are <b>variables</b>. They contain data, it's up to you what you do with that data through Twig. If you're at all familiar with any programming languages, then you likely already know the concepts. This article will provide you with the necessary knowledge to use Twig in TracCloud, regardless of your current knowledge level.
<br/><br/>
Your {{Appointment.OnlineText}} appointment with {{Consultant.FirstLast}} at
{{Appointment.StartTime}} for {{Course.SubjectCourse}} has been scheduled. If you have any
questions prior to your appointment, feel free to reach out to {{Consultant.Email}}
<br/><br/>  
Your appointment can be joined here: {{Appointment.OnlineLink}}
<br/><b/r>
Regards, {{Center.Name}}
</syntaxhighlight><br>
 
When this email is sent, all the tags we included are replaced with the relevant information for this appointment.
<br>
[[File:76y5rgeth4j75k.png|500px]]
<hr>


</div>
<span style="color:red; font-weight: bold;">Important:</span> [[TracCloud:_Rosetta|A complete list of Twig tags can be found here.]] Not all tags can be used in all places, but you can almost always predict what will and won't work in a given location. For example, in the [[TracCloud:_Emails|Appointment Confirmation Email]], you can expect to use Student, Reason, Subject, Staff tags, etc. Whereas in the [[TracCloud:_Log_Listing_Message,_KIOSK_Notices,_and_Custom_KIOSKs|Notices on KIOSK]], you can only use Center tags. This is because when that message is displayed at the top of an idle kiosk, nothing ties that message to any one Student or Staff record, let alone Registrations, Reasons, etc.
<hr>
<!-------------------------------------------- IF -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><b>if</b> / if X then do Y</big></div><div class="mw-collapsible mw-collapsed"><br><br>
<i>if</i> statements will likely be the most commonly used Twig command for most use-cases. This allows you to write out statements such as <i>“if the student selected reason “Exam Help,” then include this piece of text.”</i> Or in the example below, <i>if the appointment is online, include text to specify this.</i>
<br><br>
In the statement, we’re using the same tags that are used for emails, but without the curly brackets.


<syntaxhighlight style="border: 1px dashed black" lang="twig" line highlight="3,5">
Whenever you're using Twig, you'll see different delimiters being used.
Hello {{Student.First_Name}},
<br/><br/>
{% if Appointment.Online == "1" %}
This is an online appointment.
{% endif %}
<br/><br/>
Please be ready for the appointment at the time you selected.
</syntaxhighlight><br>


If the <i>if</i> statement is true, all text up to the endif line will be printed in the email. Since the appointment this student booked is online, the “This is an online appointment” text was included. Otherwise, it would jump straight to “Please be ready for the appointment…”
::<b><nowiki>{{ something }}</nowiki></b> - You would use this to <b>display</b> (i.e., print or echo) the contents of "something."
<br>
[[File:453j65ynh4g5rt.png|500px]]
<br><br>
We aren’t limited to just “equals” either. Similar examples with different logic can be found below.


<syntaxhighlight style="border: 1px dashed black" lang="twig" line>
::<b><nowiki>{% something %}</nowiki></b> - You would use this to <b>execute</b> something, typically to create conditions (e.g., <i>if</i> statements).
{% if Course.Subject starts with "Chem" %}
this text is only included if our subject starts with “Chem”. This is case-sensitive.  
{% endif %}


{% if Course.SubjectCourse ends with "101" %}
::<b><nowiki>{# something #}</nowiki></b> - This is a comment. Whatever you write between the hashes will not be displayed. These are handy to make notes for yourself or other admins inside emails and messages.
This text is only included if our subject ends with “101”
{% endif %}


{% if Appointment.Online != "1" %}
Here's how those would work in practice. If we sent this to a student named "John," they would receive the message on the right. Notice how the conditional text was handled, and that the comment wasn't shown.
This text is only included if the appointment is not online
{% endif %}


{% if Course.Subject == "Math" or Course.Subject == "Chem" %}
<hr style='margin-bottom: 0px;'>
This text is only included if the subject is Math or Chem
<div style='width: 49%; float: left;'>
{% endif %}
<syntaxhighlight lang="twig">
Hi {{Student.First_Name}}!


{% if Course.Subject == "Math" and Center.Name == "Math Center" %}
{% if Student.First_Name == 'Jane' %}
This text is only included if the subject is Math and the center is Math Center
    Your name is Jane.
{% else %}
    Your name is not Jane.
{% endif %}
{% endif %}


{# I never said this example would be realistic #}
    </syntaxhighlight>
</div>
<div style='width: 49%; float: right;'>
    <blockquote style="margin-top: 15px;">
    Hi John!


{% if Course.Subject == "Math" and (Center.Name == "SI" or Center.Name == "Workshop") %}
    Your name is not Jane.
This text is only included if the subject is Math and the center is SI or Workshop
    </blockquote>
{% endif %}
</div>
<hr>


{% if (CalcMissedAppointments(Student.Sequence, Center.ProfileID) > 0) %}
Now here's a more realistic example.
You have {{CalcMissedAppointments(Student.Sequence, Center.ProfileID)}} missed
appointments since {{CalcMissedDate(Center.ProfileID)}}.
{% endif %}
</syntaxhighlight><br>


<big><i>Other Examples</i></big>
<hr style='margin-bottom: 0px;'>
<div style='width: 49%; float: left;'>
<syntaxhighlight lang="twig">
Hi {{Student.First_Name}},


<hr>
Your appointment has been scheduled for {{Appointment.StartTime}} on {{Appointment.Day}}, {{Appointment.StartDate}} with {{Consultant.FirstLast}}.
"<b>If student is on a Watch List.</b>" Watch List sequence can be retrieved by hovering your mouse over the Watch List name in your System Preferences.


<syntaxhighlight style="border: 1px dashed black" lang="twig" line>
{% if Appointment.Online == 1 %}
{% if Student.WatchLists.wl_14 == "true" %}
    Click here to join your appointment: {{Appointment.OnlineLink}}.
This student is on the Athletes list!
{% endif %}
{% endif %}
</syntaxhighlight>
</syntaxhighlight>
</div>
<div style='width: 49%; float: right;'>
    <blockquote style="margin-top: 15px;">
    Hi John,
    Your appointment has been scheduled for 04:00pm on Thursday, 04/02/26 with Dave Smith.
    </blockquote>
</div>
<hr>
<hr>
Modify who receives an email based on a custom field, specific to <b>Send Visit Notes to Coach, Advisor or Student.</b><br><br>


<b>To Address of Recipient of the Notes (Coach, Advisor, Student)</b> - Only include emails selected from a multi-checkbox custom field, only include semi-colon if needed.
==Part 2. <i>if</i> Statements==
<syntaxhighlight style="border: 1px dashed black" lang="twig" line>
 
{% set var2 = 0 %}
The vast majority of the logic you're likely to build with Twig will be <i>if</i> statements. Simply, "if A, do X." You could also do "if A, do X. Otherwise if B, do Y. Otherwise if C, [...]" and so on. For a realistic example, "if the student selected the reason 'Exam Help,' then include the following paragraph" or "if the appointment is online, include the online meeting link."
{% if "Student" in Visit.CustomData.cf_104 %}
 
    {% if var2 >= 1 %};{% endif %}
An <i>if</i> statement always begins with <nowiki>{% if [...] %}</nowiki> and ends with <nowiki>{% endif %}</nowiki>. When building emails and messages, you will be working with Twig tags (variables) in these statements. So the following...
    {{Student.Email}}
 
    {% set var2 = 1 %}
<syntaxhighlight lang="twig">
{% if 2 > 1 %}
    two is greater than one!
{% endif %}
{% endif %}
{% if "Faculty" in Visit.CustomData.cf_104 %}
 
    {% if var2 >= 1 %};{% endif %}
{% if 1 == 1 %}
     {{Faculty.Email}}
     1 is the same as 1!
    {% set var2 = 1 %}
{% endif %}
{% endif %}
{% if "Consultant" in Visit.CustomData.cf_104 %}
 
    {% if var2 >= 1 %};{% endif %}
{% if "foo" != "bar" %}
     {{Staff.Email}}
     "foo" is a different word than "bar"!
    {% set var2 = 1 %}
{% endif %}
{% endif %}
{% if "SysAdmin Dave Smith" in Visit.CustomData.cf_104 %}
</syntaxhighlight>
    {% if var2 >= 1 %};{% endif %}
 
     example@school.edu
...functions just like this. [[TracCloud:_Rosetta|Once again, a list of these tags and definitions are available here.]]
    {% set var2 = 1 %}
 
<syntaxhighlight lang="twig">
{% if Appointment.Online == 1 %}
     This is an online appointment, click the following to join....
{% endif %}
{% endif %}
</syntaxhighlight><br>


<b>`Who` Label of the Button for Sending the Notes</b> - Modify the phrasing of this button based on the options selected.
{% if Reason.ReasonName == "Writing Support" %}
<syntaxhighlight style="border: 1px dashed black" lang="twig" line>
    Please remember to upload your paper to your appointment. Here's how...
{% set var = 0 %}
{% for key,value in Visit.CustomData.cf_104 %}
{% if value != "#NULL#" %}
{% if var >= 1 %},
{% endif %}
{% endif %}
{{ value|trim(' ') }}
</syntaxhighlight>
{% set var = 1 %}
 
{% endif %}
You can add <i>else</i> and <i>elseif</i> statements before the <i>endif</i> too, to handle alternate cases easily (rather than multiple separate <i>if...endif</i> statements for every condition).
{% endfor %}
</syntaxhighlight><br>


<b>'if' statement based on availability type</b> - One-on-one, group, etc.
<syntaxhighlight lang="twig">
<syntaxhighlight style="border: 1px dashed black" lang="twig" line>
{% if Appointment.Online == 1 %}
{% if Appointment.AvailRecID != "0" %}
    Join Virtually: {{Appointment.OnlineLink}}
{% if AvailBlock.MaxStudents > "1" %}
{% elseif Appointment.Online == 2 %}
This is a multi-person appointment with {{AvailBlock.MaxStudents}} slots, make sure you do X
    Accessing your Appointment: Login to TracCloud to view your asynchronous appointment.
{% elseif Appointment.Online == 3 %}
    We will call for your phone appointment at your chosen time.
{% else %}
{% else %}
This is a one-on-one appointment, make sure you do Y
    In-person location: {{Appointment.Location}}
{% endif %}
{% else %}
{% else %}
This is an ad-hoc appointment, make sure you do Z
</syntaxhighlight>
 
To check multiple conditions, <i>and</i> and <i>or</i> statements can be used.
 
<syntaxhighlight lang="twig">
{% if Reason.ReasonName == "Academic Coaching" and Student.WatchLists.wl_14 == 'true' %}
    Please remember to bring XYZ to this appointment.
{% endif %}
{% endif %}
</syntaxhighlight>
</div>
<hr>
<!-------------------------------------------- ELSE -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><b>else</b> / if X then do Y, otherwise do Z</big></div><div class="mw-collapsible mw-collapsed"><br><br>
An else statement allows us to include a block of text or an additional instruction if an <i>if</i> statement ends up not being true. For example, if our appointment above turns out to be an in-person appointment, maybe we want to include a different string of text.


<syntaxhighlight style="border: 1px dashed black" lang="twig" line highlight="3,5,7">
{% if Reason.ReasonName == "Peer Tutoring" or Consultant.CustomData.cf_123 == 'true' %}
Hello  {{Student.First_Name}},
    You have booked an appointment with a Peer Tutor!
<br/><br/>
{% if Appointment.Online == "1" %}
This is an online appointment.
{% else %}
This is an in-person appointment.
{% endif %}
{% endif %}
<br/><br/>
</syntaxhighlight>
Please be ready for the appointment at the time you selected.
</syntaxhighlight><br>


Since the appointment wasn’t online, we get the “This is an in-person…” text in our confirmation email instead.
A list of operators can be found in part 4.
<br>
[[File:57j57k7k7lkk.png|500px]]
</div>
<hr>
<!-------------------------------------------- elseif -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><b>elseif </b> / if W then do X, otherwise if Y then do Z</big></div><div class="mw-collapsible mw-collapsed"><br><br>
An <i>elseif</i> statement allows us to ask additional <i>if</i> questions, assuming the answer to the prior question was No.


<syntaxhighlight style="border: 1px dashed black" lang="twig" line highlight="3,5,7">
==Part 3. Working with Arrays==
Hello  {{Student.First_Name}},
<br/><br/>
{% if Course.Subject == "Math" %}
This appointment is for Math
{% elseif Course.Subject == "Chem" %}
This appointment is for Chem
{% endif %}
<br/><br/>
Please be ready for the appointment at the time you selected.
</syntaxhighlight><br>


Since our appointment was for Chemistry, we receive the following email. If the appointment was for neither Chemistry nor Math, we wouldn’t see a middle block of text at all.
>95% of Twig tags you will work with in TracCloud contain single values, but a very small number of fields are <b>arrays</b> containing multiple values. Most notably, [[TracCloud:_SAGE|SAGE]] reasons & recommendations and Multiple Checkbox [[TracCloud:_Custom_Fields|custom fields]].
<br>
[[File:45j67j5nl68k67.png|500px]]
</div>
<hr>
<!-------------------------------------------- if arrays -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><b>if (arrays)</b> / if X in Y</big></div><div class="mw-collapsible mw-collapsed"><br><br>
When you want to use an <i>if</i> statement for arrays, such as the Reasons and Recommendations for SAGE referrals, the formatting is a little bit different. In this context, you would want to know if the Reasons array contains the reason you’re looking for. This would be formatted as such:


<syntaxhighlight style="border: 1px dashed black" lang="twig" line highlight="3,5">
As an example, take Student.First_Name. This field can only contain one value at any given time. <i>Student.First_Name</i> = Jane, so <nowiki>{{Student.First_Name}}</nowiki> outputs Jane. But how about the <i>Reasons</i> field in SAGE referrals? This is an array that contains "Poor Grades" and "Acceptable Attendance" and "Lack of Focus." If we try to use <nowiki>{{Reasons}}</nowiki>, we'll get an error. That's where we have to take a slightly different approach, using the <i>for</i> tag.
Hello {{Student.First_Name}},
<br/>
{% if "Poor Grades" in Reasons %}
This referral is being submitted due to the reason “Poor Grades”
{% endif %}
</syntaxhighlight><br>


Since “Poor Grades” was the reason our faculty member selected when submitting this referral, we receive the following email.
Here's how this works, with an example variable so you can see what it's working with. For each item in the "exampleField" array, it prints the item (and adds a <nowiki><br></nowiki> tag to insert a line break).
<br>
[[File:566776lyujhg.png|500px]]
<br><br>
We can also search for the opposite, specifying “not in” instead:


<syntaxhighlight style="border: 1px dashed black" lang="twig" line>
<hr style='margin-bottom: 0px;'>
{% if "Poor Grades" not in Reasons %}
<div style='width: 49%; float: left;'>
This referral was *not* created with the reason “Poor Grades”
<syntaxhighlight lang="twig">
{% endif %}
{% set exampleField = ['a','b','c'] %}
   
{% for item in exampleField %}
    {{item}}<br>
{% endfor %}
</syntaxhighlight>
</syntaxhighlight>
</div>
<div style='width: 49%; float: right;'>
    <blockquote style="margin-top: 15px;">
    a<br>
    b<br>
    c<br>
    </blockquote>
</div>
</div>
<hr>
<hr>
<!-------------------------------------------- For arrays-------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><b>for (arrays)</b> / for each X in Y, do Z</big></div><div class="mw-collapsible mw-collapsed"><br><br>
The <i>for</i> command allows us to list out the contents from a specific sequence. This would frequently be used for listing out Reasons or Recommendations in SAGE referral emails.


<syntaxhighlight style="border: 1px dashed black" lang="twig" line highlight="3,5,9,11">
Now back to our SAGE example. Remember, Reasons is an array that contains ['Poor Grades','Acceptable Attendance','Lack of Focus'].
This referral is being submitted because of these reasons:
 
<br/>
<hr style='margin-bottom: 0px;'>
{% for key,value in Reasons %}
<div style='width: 49%; float: left;'>
    {{ value }} <br/>
<syntaxhighlight lang="twig">  
{% endfor %}
{% for item in Reasons %}
<br/><br/>
     {{item}}<br>
And these recommendations:
<br/>
{% for key,value in Recommendations %}
     {{ value }} <br/>
{% endfor %}
{% endfor %}
</syntaxhighlight><br>
</syntaxhighlight><br>
 
</div>
[[File:6j57k6jthngfbv.png|500px]]
<div style='width: 49%; float: right;'>
<br><br>
    <blockquote style="margin-top: 15px;">
Alternatively, Array tags such as ReferralType.Reasons will need to be formatted as such:
    Poor Grades<br>
 
    Acceptable Attendance<br>
<syntaxhighlight style="border: 1px dashed black" lang="twig" line>
    Lack of Focus<br>
{% for item in ReferralType.Reasons %}
    </blockquote>
{{ item.value|e }}
{% endfor %}
</syntaxhighlight>
</div>
</div>
<hr>
<hr>
<!-------------------------------------------- SAGE QUESTIONS-------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><b>SAGE Questions & Actions</b></big></div><div class="mw-collapsible mw-collapsed"><br><br>
Custom questions within SAGE have one more moving part to take into consideration. When creating a custom question, there’s a field named “Code Reference.” This is the code used when referring to this question in emails and reports.
<br>
[[File:64ik6ughntr6.png|500px]]
<br><br>
These questions/answers are part of an array, utilized just like the Reasons and Recommendations above.


<syntaxhighlight style="border: 1px dashed black" lang="twig" line>
You can also check if a value is in an array as an <i>if</i> statement like this. Inversely, you can do <i>not in</i> instead of <i>in</i> to check if a value is not in an array.
Hi, this referral has been submitted:
 
<br/><br/>
<syntaxhighlight lang="twig">
{% if Answers.VisitQuestion != '' %}
{% if 'Poor Grades' in Reasons %}
You answered {{Answers.VisitQuestion}} to the question {{Questions.VisitQuestion}}
    Here are some great resources to improve your study habits...
{% endif %}
{% endif %}
<br/><br/>
{% for key,value in Answers %}
The answer to question {{ attribute(Questions, key) }} is {{ value }}
<br/>
{% endfor %}
</syntaxhighlight><br>


First, we’re looking for a specific question and answer. To pull this information, we’re using the tags “<i>Answers.[Code Reference]</i>” and “<i>Questions.[Code Reference]</i>”, with the code reference portion being replaced with whatever we entered in the SAGE custom question. If this question was answered, we’re going to include our answer and the question itself in the email.
{% if "Meet with Advisor" in Recommendations %}
<br><br>
    We recommended that you meet with your advisor, here's how to schedule...
Secondly, we want to go through all of our answers to all of our questions. This would be an array just like Reasons and Recommendations, and is formatted similarly. Once we receive this email, we will see the answers selected by our faculty member.
{% endif %}
<br>
</syntaxhighlight>
[[File:Qeh3536j46j3hbeg.png|500px]]
<hr>


==Actions==
More Twig examples and tag definitions for SAGE emails can be found [[TracCloud:_SAGE|here.]]
Actions can be used as commands in addition to Twig. At this time, the only Action that has been implemented is <i>#ACTION:DO NOT SEND#</i>, which prevents the email from being sent. This is primary used in [[TracCloudSAGE|SAGE]] emails, but can also be used in [[TracCloudGuideProfilePrefsEmails|profile emails]] if needed. For example, this could be useful in situations where not all of your SAGE referrals need to result in an email being sent. You could have a dedicated recommendation for “No recommendations at this time”, and we could use that to determine whether or not an email gets sent.


<syntaxhighlight style="border: 1px dashed black" lang="twig" line highlight="14">
==Part 4. Tips and Tricks==
{% if "No recommendations at this time" not in Recommendations %}
This referral is being submitted because of these reasons:
<br/>
{% for key,value in Reasons %}
    {{ value }} <br/>
{% endfor %}
<br/><br/>
And these recommendations:
<br/>
{% for key,value in Recommendations %}
    {{ value }} <br/>
{% endfor %}
{% else %}
#ACTION:DO NOT SEND#
{% endif %}
</syntaxhighlight><br>


With this email configuration in place, if our faculty member submits a referral with the recommendation “No recommendations at this time,” no email would be sent. An email will only be sent if that recommendation wasn’t selected, which would then follow the rest of the example above, listing out reasons and recommendations.
The remainder of this article covers some extra tips and tricks, as well as unique functions that may be of use.
</div>
<hr>


==Tag List==
===4.1. Special Tags===
The remainder of this chapter will display all of the email tags available in TracCloud with definitions.
<br><br>
For most of these tags, you can print the relevant value by surrounding the field with double-curly brackets, as seen in several of the above twig examples. The curly brackets are not required when using the value in an <i>if</i> statement, for example.
<hr>
<!-------------------------------------------- STUDENT TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Student tags</i></big></div><div style="float: right">[[TracCloud:_Rosetta|Moved {{#fas:arrow-up-right-from-square}}]]</div><br>
<hr>
<!-------------------------------------------- APPOINTMENT/AVAILABILITY TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Appointment & Availability tags</i></big></div><div style="float: right">[[TracCloud:_Rosetta|Moved {{#fas:arrow-up-right-from-square}}]]</div><br>
<hr>
<!-------------------------------------------- Center/Reason TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Center & Reason tags</i></big></div><div class="mw-collapsible mw-collapsed"><br><br>
{| class="wikitable"
|-
| Center.Name || The appointment/visit center
|}


TracCloud has a few special functions listed below that can be used to prevent an email from sending, CC additional recipients, automatically get special values, and more. More of these functions are available specifically for certain modules, such as [[TracCloud:_SAGE|SAGE Early Alerts]], [[TracCloud:_Success_Plans|Success Plans]], and [[TracCloud:_Work_Plans|Work Plans]]. Visit the emails/Twig sections of those articles to learn more. The ones listed below are available throughout TracCloud.


{| class="wikitable"
{| class="wikitable"
|-
|-
| Reason.ReasonName || The appointment/visit reason
| <nowiki>{{CalcMissedAppointments(Student.Sequence, Center.ProfileID)}}</nowiki> || The student's total number of missed appointments since the date specified in your profile Scheduling Prefs. Uses System Pref date if Profile date is blank.
|-
|-
| Reason.Category || The reason category
| <nowiki>{{CalcMissedDate(Center.ProfileID)}}</nowiki> || Your profile “Calc Missed Appointments Since” date. If this field is blank, this will use your global Calc Missed date instead.
|}
</div>
<hr>
<!-------------------------------------------- Section TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Section, Course, & Faculty tags</i></big></div><div style="float: right">[[TracCloud:_Rosetta|Moved {{#fas:arrow-up-right-from-square}}]]</div><br>
<hr>
<!-------------------------------------------- Consultant TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Consultant/Staff tags</i></big></div><div class="mw-collapsible mw-collapsed"><br><br>
{| class="wikitable"
|+ ("Consultant." or "Staff." prefixes can be used interchangeably)
|-
|-
| Consultant.First_Name || Consultant's first name
| <nowiki>{{setAdditionalCC('address@domain.edu,address2@domain.edu')}}</nowiki> || CC additional email addresses, can be used with 'if' statements to make the CC conditional.
|-
|-
| Consultant.Last_Name || Consultant's last name
| <nowiki>{{ GetActiveTermFrom() }}</nowiki> || Can be used to get the start date of your current active term(s).
|-
|-
| Consultant.LastFirst || Consultant's full name, formatted as "Last, First"
| <nowiki>{{ GetActiveTermTo() }}</nowiki> || Can be used to get the end date of your current active term(s).
|-
|-
| Consultant.FirstLast || Consultant's full name, formatted as "First Last"
| <nowiki>{{ setResultActions('SendEmail', '0') }}</nowiki> || Can be used to prevent an email from sending, similar to "#ACTION:DO NOT SEND#" in SAGE emails.
|-
|-
| Consultant.Alias || Consultant's alias
| <nowiki>{{ GetDatePlusDays(5) }}</nowiki> || Get the current date plus the number of days specified in parentheses
|-
|-
| Consultant.Email || Consultant's email address
| <nowiki>{{ GetDateTimePlusDays(5) }}</nowiki> || Get the current date AND time plus the number of days specified in parentheses
|-
| Consultant.Phone || Consultant's phone number
|-
| Consultant.Pronouns || Consultant's preferred pronouns
|-
| Consultant.Photo<nowiki>|raw</nowiki> || Consultant's photo
|-
| Consultant.StaffBIO<nowiki>|raw</nowiki> || Consultant's bio
|-
| Consultant.WorkPhone || Consultant's work phone number
|-
| Consultant.CellPhone || Consultant's cell phone number
|-
| Consultant.CustomData.cf_0 || Custom fields, hover over each field in the Email Tag list to find the correct tag
|}
</div>
<hr>
<!-------------------------------------------- Visit TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Visit tags</i></big></div><div style="float: right">[[TracCloud:_Rosetta|Moved {{#fas:arrow-up-right-from-square}}]]</div><br>
<hr>
<!-------------------------------------------- Document TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Document tags</i></big></div><div class="mw-collapsible mw-collapsed"><br><br>
{| class="wikitable"
|+ (only for document emails)
|-
| Document.OrigName || The file name (including file extension)
|-
| Document.Notes || Notes entered during document upload
|-
| Document.PostedBy || The UUID of who uploaded this document
|-
| Document.PostedByName || The user type, sequence, and name of who uploaded this document
|-
| Document.Usage || Where this document was uploaded, e.g., Appointment, Student, Availability
|-
| DocType.Name|| The document type selected during upload
|}
|}


</div>
===4.2. List of Operators===
<hr>
 
<!-------------------------------------------- Resource TAGS -------------------------------------------->
Beyond the basics like == (equals) and != (not equals), there are plenty more operators available depending on what you want to accomplish.
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Resource tags</i></big></div><div class="mw-collapsible mw-collapsed"><br><br>
 
{| class="wikitable"
{| class="wikitable"
|+ (only for resource emails)
|-
|-
| Resource.Title || The name of the resource
! Operator !! Description !! True Example
|-
|-
| Resource.Barcode || The barcode value of the resource
| == || Equals || <nowiki>{% if 1 == 1 %}</nowiki>
|-
|-
| Resource.Description || The description of this resource
| != || Does not equal || <nowiki>{% if 'a' != 'b' %}</nowiki>
|-
|-
| Resource.CustomData.PickupInstructions || Instructions for pickup for this resource.
| > || Greater than || <nowiki>{% if 2 > 1 %}</nowiki>
|-
|-
| Resource.CustomData.ReturnInstructions || Instructions for return for this resource.
| < || Less than || <nowiki>{% if 1 < 2 %}</nowiki>
|-
|-
| Resource.Keywords || The keywords for this resource, which can be used to check the item in or out
| in || Is contained by (for arrays) || <nowiki>{% if 'a' in ['a','b','c'] %}</nowiki>
|-
|-
| Resource.Status || The status of the resource, "-1" is Inactive, "0" is Checked out, "1" is available and not checked out, "2" is always available
| not in || Is not contained by (for arrays) || <nowiki>{% if 'z' not in ['a','b','c'] %}</nowiki>
|-
|-
| Resource.MaxDaysOut || The maximum number of days that an item can be checked out
| starts with || Begins with || <nowiki>{% if 'abc' starts with 'a' %}</nowiki>
|-
|-
| Resource.MaxTimeOut || The maximum amount of time that an item can be checked out
| ends with || Concludes with || <nowiki>{% if 'abc' ends with 'c' %}</nowiki>
|-
|-
| Checkout.Date || The resource checkout date
|-
| Checkout.Collateral || The collateral collected from the student during checkout
|-
| Checkout.Overdue || Whether or not this item is overdue, formatted as "0" (not overdue) or "1" (overdue)
|-
| Checkout.DueDT || The date and time that the item is due to be returned, formatted as "2020-01-31 13:00:00"
|-
| ResourceType.Name || The name of the resource type that the resource is assigned to
|-
| ResourceType.Description || The description of the resource type that the resource is assigned to
|}
|}
</div>
<hr>
<!-------------------------------------------- Survey TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>SurveyTrac tags</i></big></div><div class="mw-collapsible mw-collapsed"><br><br>


{| class="wikitable"
===4.3. Filters===
|-
| Survey.Name || The name of a survey, for use in survey emails. [[TracCloudST|More information.]]
|-
| Survey.Link || A hyperlink to the survey, for use in survey emails.
|-
| Survey.URL || A URL to the survey, for use in survey emails.
|}


</div>
Filters can be used to modify or change the data stored in variables. One of the most common examples is using the 'date' filter to modify the format of dates in emails. For example, <nowiki>{{Appointment.StartDT}}</nowiki> would return 2026-01-31 14:00:00, while <nowiki>{{Appointment.StartDT|date("D, F j, h:ia")}}</nowiki> would return "Sat, January 31, 02:00pm." ([https://www.php.net/manual/en/datetime.format.php click here for a list of datetime format codes]). A list of some of the supported filters and functions in TracCloud can be found below.
<hr>
<!-------------------------------------------- Custom Field TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Custom Field tags</i></big></div><div class="mw-collapsible mw-collapsed"><br><br>
{| class="wikitable"
|+ (Replace "123" with your Custom Field sequence number)
|-
| CustomFields.cf_123.DataName || The internal field name of the specified custom field
|-
| CustomFields.cf_123.Prompt || The external/prompt text of the specified custom field
|-
| CustomFields.cf_123.Choices || [Array] The available choices for the specified custom field (separate from selected choices)
|}


</div>
<hr>
<!-------------------------------------------- SAGE TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>SAGE tags</i></big></div><div class="mw-collapsible mw-collapsed"><br><br>
<section begin="SAGETags" />
{| class="wikitable"
{| class="wikitable"
|-
|-
| ReferralType.Name || The name of the referral that has been submitted
! Filter !! Description !! Example !! Output
|-
|-
| ReferralType.RosterSubject || [Array] The roster subject, e.g., “Chem”
| date || Change the format of a date field || <nowiki>{{Appointment.StartDT|date("Y-m-d")}}</nowiki> || 2026-01-31
|-
|-
| ReferralType.NotesInstructions || These are the instructions written out in within the referral settings
| lower || Changes contents to lowercase || <nowiki>{{Student.First_Name|lower}}</nowiki> || jane
|-
|-
| ReferralType.Reasons || [Array] Lists all referral Reasons, regardless of what was selected.
| upper || Changes contents to uppercase || <nowiki>{{Student.First_Name|upper}}</nowiki> || JANE
|-
|-
| ReferralType.Recommend || [Array] Lists all referral Recommendations, regardless of what was selected.
| trim || Trim spaces or text from the start and end of a string || <nowiki>{{Student.Email|trim('@example.edu')}}</nowiki> || jdoe
|-
| ReferralType.AdditionalNotesInstr || These are the additional notes written out within the referral settings
|}
|}


===4.4. Indentation===


{| class="wikitable"
Twig is not indentation sensitive. Most of the examples in this article use indentation to improve readability, but it will function regardless of it. All three of the examples below will function identically.
|-
 
| Referral.CreatedBy || The name of the faculty member that submitted this referral
<syntaxhighlight lang="twig">   
|-
{% if Appointment.Online == 1 %}
| Referral.CreatedDT || When this referral was created
    This is an online appointment!
|-
{% endif %}
| Referral.NotesInstrData || Notes entered while submitting this referral
 
|-
{% if Appointment.Online == 1 %}
| Referral.AdditionalNotes || Additional notes entered while submitting this referral
This is an online appointment!
|-
{% endif %}
| Referral.ReasonsData || [Array] Selected reasons, “Reasons” is preferred (see “For” examples above).
 
|-
{% if Appointment.Online == 1 %}This is an online appointment!{% endif %}
| ReasonsAndLabels || [Array] Same as above, but this will also include your Reason labels in the email body.
</syntaxhighlight>
|-
 
| Referral.RecommendData || [Array] Selected recommendations, “Recommendations” is preferred (see “For” examples above).
===4.5. Streamlining Twig Statements===
|-
 
| RecommendationsAndLabels || [Array] Same as above, but this will also include your Recommendation labels in the email body.
If you find yourself writing something like this:
|-
 
| Referral.FollowUpDate || The date this referral should be followed up on
<syntaxhighlight lang="twig">
|-
{% if Reason.ReasonName == 'X' or Reason.ReasonName == 'Y' or Reason.ReasonName == 'Z' %}
| Referral.FollowUpBy || The name of the staff who followed up on this referral
</syntaxhighlight>
|-
 
| Referral.FollowedUp || If a follow-up has been saved, display “1”, otherwise blank
Try using an array instead. Both will work, but the latter is cleaner and easier to update later.
|-
| Referral.FollowedUpDT || The date this referral was followed up on
|-
| Referral.FollowedUpBy || Who this referral was followed up by
|-
| Referral.Processed || If this referral has been processed, display “1”, otherwise blank
|-
| Referral.ProcessedDT || The date/time this referral was marked as processed/completed
|-
| Referral.ProcessedBy || The written date/time this referral should be marked as processed
|-
| Referral.ProcessedNotes || Notes entered when marking the referral as processed
|-
| Referral.StudentContacted || The date that the student was contacted
|-
| Referral.CustomData.AssignedConsultantID || The sequence number of the assigned consultant.
|}


<syntaxhighlight lang="twig">
{% if Reason.ReasonName in ['X','Y','Z'] %}
</syntaxhighlight>


{| class="wikitable"
|-
| Trigger || The trigger for this email, “Created”, “Followed Up”, or “Processed”
|-
| Email.Subject || The contents of the email subject line
|-
| Questions.CODE || Questions.[Your custom question code], as covered above
|-
| Answers.CODE || Answers.[Your custom question code], as covered above
|-
| <nowiki>{{ setResultActions('AssignConsultant', '</nowiki><span style="color:red">123</span><nowiki>') }}</nowiki> || If this line is reached within a SAGE email, the assigned staff member will be changed to the specified sequence. The example below shows how you can use this script to link a student's assigned advisor to the referral.
|-
| || <nowiki>{% set staffSeq = getRecordFieldData('Staff','Email', Student.CustomData.cf_1,'Sequence') %}</nowiki><br><nowiki>
{{ setResultActions('AssignConsultant', staffSeq) }}</nowiki>
|-
| <nowiki>{{ setResultActions('SendEmail', '0') }}</nowiki> || If this line is reached within an email, the email will not be sent
|-
| <nowiki>{{ setResultActions('SetProcessed', '1') }}</nowiki> || If this line is reached within an email, the referral will be marked as processed/completed.
|-
| <nowiki>{{ setResultActions('SetProcessedNotes', 'Example notes') }}</nowiki> || Typically used alongside the tag above. Used to automatically add notes to the processed referral.
|}
<section end="SAGETags" />
</div>
<hr>
<hr>
<!-------------------------------------------- Success Plan TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Success Plan tags</i></big></div><div class="mw-collapsible mw-collapsed"><br><br>
<section begin="SPTags" />
{| class="wikitable"
|+ Success Plans
|-
| SuccessPlan.Name || The name of your Success Plan
|-
| SPAssigned.DateStarted || Start Date of the Success Plan
|-
| SPAssigned.DateCompleted || Completion Date of the Success Plan
|-
| SPAssigned.DueDate || Due Date for Success Plan
|-
| SPAssigned.Status || The Status of the Success Plan (e.g., "In Progress")
|-
| SPAssigned.Percent || The completion percentage of the Success Plan (e.g., 75)
|-
| SPAssigned.DashboardStatus|raw || The text that would appear on the student's main menu showing their progress in the plan.
|-
| SPStep.Sequence || The sequence of the current Step
|-
| SPStep.Type || The type of the current step (e.g., Visit, Task, etc.)
|-
| SPStep.DateOrOffset || When this Step needs to be completed (number of days or static date based on Plan type)
|-
| SPStep.isOptional || Whether or not the current Step is optional (1 or 0)
|-
| SPStep.isNoSendEmails || Whether or not emails are disabled for this Step (1 or 0)
|-
| SPStep.isPromptOnDash || Whether or not the prompt is set to display on the dashboard (1 or 0)
|-
| SPStep.DirectedTo || Who the confirmation is directed to (0 = Student, 1 = Plan Staff, 2 = Plan Faculty, 3 = Step Staff, 4 = Step Faculty)
|-
| SPStep.OverrideRequireConfirmation || Whether or not this step has been overridden to allow/disallow confirmation
|-
| SPAssignedStep.CompletedDate || The completion date of your Success Plan Step
|-
| SPAssignedStep.DueDate || The due date of your Success Plan Step
|-
| SPAssignedStep.CompletionOverride || Whether or not the completion override option is enabled for this Step (1 or 0)
|-
| SPAssignedStep.StaffNotes || Any notes entered by staff for this Step
|-
| SPAssignedStep.Confirmed || Whether or not this Step has been confirmed (1 or 0)
|-
| SPAssignedStep.Index|| The number of the step, based on the order they were created in.
|}


If you're repeatedly checking the same condition, like this:
<syntaxhighlight lang="twig">
Your {% if Appointment.Online == '1' or Appointment.CustomData.cf_123 == 'Hybrid Appt' %} online {% endif %} appointment has been scheduled for...
Location: {% if Appointment.Online == '1' or Appointment.CustomData.cf_123 == 'Hybrid Appt' %} To join, please click... {% endif %}...
Appointment policies: {% if Appointment.Online == '1' or Appointment.CustomData.cf_123 == 'Hybrid Appt' %} Please remember to... {% endif %}...
</syntaxhighlight>
Consider setting a variable once and using that instead:
<syntaxhighlight lang="twig">
{% if Appointment.Online == '1' or Appointment.CustomData.cf_123 == 'Hybrid Appt' %}
    {% set online = true %}
{% else %}
    {% set online = false %}
{% endif %}
Your {% if online %} online {% endif %} appointment has been scheduled for...
Location: {% if online %} To join, please click... {% endif %}...
Appointment policies: {% if online %} Please remember to... {% endif %}...
</syntaxhighlight>


{| class="wikitable"
|+ Other
|-
| <nowiki>{{Trigger}}</nowiki> || The trigger that prompted this email to be sent (trigger_PlanStarted, trigger_PlanReminder1, trigger_PlanComplete, trigger_StepStarted, etc.)
|-
| <nowiki>{{ setResultActions('SendEmail', '0') }}</nowiki> || If this action is reached (typically in a Twig 'if' statement), the email will not be sent
|-
| <nowiki>{{ setResultActions('FacultyID', '1') }}</nowiki> || If this action is reached (in a Twig statement), the assigned Faculty will be changed to the sequence number specified here
|-
| <nowiki>{{ setResultActions('ConsultantID', '1') }}</nowiki> || If this action is reached (in a Twig statement), the assigned Consultant will be changed to the sequence number specified here
|-
| <nowiki>{{ setResultActions('TermID', '1') }}</nowiki> || If this action is reached (in a Twig statement), the assigned Term will be changed to the sequence number specified here
|-
| <nowiki>{{ setResultActions('NextPlanID', '3') }}</nowiki> || If this action is reached (in a Twig statement), a new Success Plan will be assigned (for use in Chained Sub Plans)
|-
| <nowiki>{{ GetDatePlusDays(5) }}</nowiki> || Get the current date plus the number of days specified in parentheses
|-
| <nowiki>{{ GetDateTimePlusDays(5) }}</nowiki> || Get the current date AND time plus the number of days specified in parentheses
|-
| <nowiki>{{ createResultAction('createNotification', {'Type' : 1, 'Notes' : 'Sample Notes', 'StudentID': Student.Sequence, 'ForUID' : Student.UUID}) }}</nowiki> || If this action is reached (in a Twig statement), the student will be sent a Notification. Enter the notification sequence where the '1' is in this example.
|-
| <nowiki>{{ createResultAction('createSurvey', {'SurveyID' : 1, 'StudentID': Student.Sequence, 'linkedUID' : Student.UUID}) }}</nowiki> || If this action is reached (in a Twig statement), the student will be sent a Survey. Enter the Survey sequence where the '1' is in this example.
|-
| <nowiki>{{ createResultAction('createReferral', {'RefTypeID' : 1, 'StudentID': Student.Sequence, 'FacultyID' : 0, 'SectionID' : 0, 'ConsultantID' : 0, 'CenterID' : 0, 'ReasonsData' : [{"key": "###keyIndex###","reason": "Time management"}]}) }}</nowiki> || If this action is reached (in a Twig statement), a SAGE Referral will be created for the student. Enter the Referral sequence where the "1" is in this example. Additional assignments can also be made.
|-
| <nowiki>{{ createResultAction('createAssignment', {'PotentialAssignmentID' : 1, 'StudentID': Student.Sequence, 'RegistrationID' : GetStudentRegID(Student.ID,'MAT100 0000 FALL%'), 'GradePoints' : 0, 'Comments' : 'Notes go here'}) }}</nowiki> || If this action is reached (in a Twig statement), an Assignment will be created for the student. Enter the potential assignment sequence where the '1' is, and choose the section.
|-
| <nowiki>{{ createResultAction('createTask', {'TaskType' : 0, 'ForUID' : Student.UUID, 'StudentID': Student.Sequence, 'TaskName' : 'Test of Task Name', 'DueDate' : '2030-01-01', 'Completed' : 0 }) }}</nowiki> || If this action is reached (in a Twig statement), a Task will be assigned to the Student. Enter the Task sequence where the '0' and choose a due date.
|-
| <nowiki>{{ createResultAction('updateStudent', {'Major' : 'Business', 'CustomData.cf_99' : "Text goes here' }) }}</nowiki> || If this action is reached (in a Twig statement), student fields can be updated to the text specified here. Multiple fields can be edited at once (Major and Custom_99 in this example). Field names are case sensitive.
|}
<section end="SPTags" />
</div>
<hr>
<hr>
<!-------------------------------------------- Work Plan TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Work Plan tags</i></big></div><div class="mw-collapsible mw-collapsed"><br><br>
<section begin="WPTags" />
{| class="wikitable"
|+ Work Plans
|-
| WorkPlan.Name || The name of your Work Plan
|-
| WPAssigned.DateStarted || Start Date of the Work Plan
|-
| WPAssigned.DateCompleted || Completion Date of the Work Plan
|-
| WPAssigned.DueDate || Due Date for Work Plan
|-
| WPAssigned.Status || The Status of the Work Plan (e.g., "In Progress")
|-
| WPAssigned.Percent || The completion percentage of the Work Plan (e.g., 75)
|-
| WPStep.Sequence || The sequence of the current Step
|-
| WPStep.Type || The type of the current step (e.g., Work Visit, Prompt, etc.)
|-
| WPStep.DateOrOffset || When this Step needs to be completed (number of days or static date based on Plan type)
|-
| WPStep.isOptional || Whether or not the current Step is optional (1 or 0)
|-
| WPStep.isNoSendEmails || Whether or not emails are disabled for this Step (1 or 0)
|-
| WPStep.isPromptOnDash || Whether or not the prompt is set to display on the dashboard (1 or 0)
|-
| WPStep.DirectedTo || Who the confirmation is directed to (0 = Consultant, 1 = Plan Supervisor)
|-
| WPStep.OverrideRequireConfirmation || Whether or not this step has been overridden to allow/disallow confirmation
|-
| WPAssignedStep.CompletedDate || The completion date of your Work Plan Step
|-
| WPAssignedStep.DueDate || The due date of your Work Plan Step
|-
| WPAssignedStep.CompletionOverride || Whether or not the completion override option is enabled for this Step (1 or 0)
|-
| WPAssignedStep.StaffNotes || Any notes entered by staff for this Step
|-
| WPAssignedStep.Confirmed || Whether or not this Step has been confirmed (1 or 0)
|}


{| class="wikitable"
This one is more minor, but in most cases instead of writing this:
|+ ("StepSupervisor." prefix can be used to retrieve supervisor information for the step instead.)
 
|-
<syntaxhighlight lang="twig">
| Supervisor.First_Name || The first name of the assigned supervisor.
{% if Appointment.Location != '' %}
|-
</syntaxhighlight>
| Supervisor.Last_Name || Last name of the assigned supervisor.
 
|-
You can write the following. This will return true if that field is not false, blank, or 0.
| Supervisor.Alias || Alias of the assigned supervisor.
|-
| Supervisor.Email || Email address of the assigned supervisor.
|-
| Supervisor.UserName || Username of the assigned supervisor.
|-
| Supervisor.FirstLast || Full name of the assigned supervisor.
|-
| Supervisor.isConsultant || Whether or not the assigned supervisor is a consultant (formatted as "1" or "0")
|-
| Supervisor.Phone || Phone number of the assigned supervisor.
|-
| Supervisor.CellPhone || Cell phone of the assigned supervisor.
|-
| Supervisor.WorkPhone || Work phone of the assigned supervisor.
|-
| Supervisor.Location || Assigned location of the supervisor.
|-
| Supervisor.OnlineLink || The assigned supervisor's online link.
|-
| Supervisor.Fund || Fund of the assigned supervisor.
|-
| Supervisor.Pronouns || Pronouns of the assigned supervisor.
|-
| Supervisor.OtherID || Other ID of the assigned supervisor.
|}


{| class="wikitable"
<syntaxhighlight lang="twig">
|-
{% if Appointment.Location %}
| StepFaculty.FirstName || First name of the linked faculty.
</syntaxhighlight>
|-
| StepFaculty.LastName || Last name of the linked faculty.
|-
| StepFaculty.UserID || User of the linked faculty. This should almost always be used instead of OtherID.
|-
| StepFaculty.UserName || Username of the linked faculty.
|-
| StepFaculty.Salutation || Salutation of the linked faculty.
|-
| StepFaculty.Department || Department of the linked faculty.
|-
| StepFaculty.Phone || Phone of the linked faculty.
|-
| StepFaculty.Email || Email address of the linked faculty.
|-
| StepFaculty.FullName || Full name of the linked faculty.
|-
| StepFaculty.Pronouns || Pronouns of the linked faculty.
|}


{| class="wikitable"
==Part 5. Getting Help==
|+ Other
|-
| <nowiki>{{Trigger}}</nowiki> || The trigger that prompted this email to be sent (trigger_PlanStarted, trigger_PlanReminder1, trigger_PlanComplete, trigger_StepStarted, etc.)
|-
| <nowiki>{{ setResultActions('SendEmail', '0') }}</nowiki> || If this action is reached (typically in a Twig 'if' statement), the email will not be sent
|-
| <nowiki>{{ setResultActions('ConsultantID', '1') }}</nowiki> || If this action is reached (in a Twig statement), the assigned Consultant will be changed to the sequence number specified here
|-
| <nowiki>{{ setResultActions('TermID', '1') }}</nowiki> || If this action is reached (in a Twig statement), the assigned Term will be changed to the sequence number specified here
|-
| <nowiki>{{ setResultActions('NextPlanID', '3') }}</nowiki> || If this action is reached (in a Twig statement), a new Work Plan will be assigned (for use in Chained Sub Plans)
|-
| <nowiki>{{ GetDatePlusDays(5) }}</nowiki> || Get the current date plus the number of days specified in parentheses
|-
| <nowiki>{{ GetDateTimePlusDays(5) }}</nowiki> || Get the current date AND time plus the number of days specified in parentheses
|}
<section end="WPTags" />
</div>
<hr>
<!-------------------------------------------- Workshop TAGS -------------------------------------------->
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Workshop tags</i></big></div><div class="mw-collapsible mw-collapsed"><br><br>
{{#lst:TracCloud: Workshops|workshopTags}}
</div>
<hr>


<!-------------------------------------------- Other TAGS -------------------------------------------->
If you're a primary SysAdmin for your TracCloud instance and you need some help with Twig or HTML, feel free to reach out to us. Scroll all the way to the top of this page and click the "Support" tab to visit our helpdesk.
<div style="float: left; margin-top: 0em; margin-bottom: 1em"><big><i>Other tags</i></big></div><div class="mw-collapsible mw-collapsed"><br><br>
{| class="wikitable"
|-
| <nowiki>{{CalcMissedAppointments(Student.Sequence, Center.ProfileID)}}</nowiki> || The student’s total number of missed appointments since the date specified in your profile Scheduling Prefs. Uses System Pref date if Profile date is blank.
|-
| <nowiki>{{CalcMissedDate(Center.ProfileID)}}</nowiki> || Your profile “Calc Missed Appointments Since” date. If this field is blank, this will use your global Calc Missed date instead.
|-
| <nowiki>{{setAdditionalCC('address@domain.edu,address2@domain.edu')}}</nowiki> || CC additional email addresses, can be used with 'if' statements to make the CC conditional.
|-
| <nowiki>{{Appointment.SchedVisitStatusIcon|raw}}</nowiki> || Can be used on the staff schedule [[TracCloudGuideProfilePrefsScheduleDisplay|appointment display]] to allow users to start & conclude the visit directly from the appointment.
|-
| <nowiki>{{ GetActiveTermFrom() }}</nowiki> || Can be used to get the start date of your current active term(s).
|-
| <nowiki>{{ GetActiveTermTo() }}</nowiki> || Can be used to get the end date of your current active term(s).
|}
</div>
<hr>


[[Category:TracCloud Manual]]
[[Category:TracCloud Manual]]
</div>
</div>

Latest revision as of 21:23, 24 April 2026

TracCloud Twig Guide

Many text fields throughout TracCloud support Twig and HTML, giving you greater control in determining what data is displayed to your students, staff, and faculty based on the context of appointments, visits, and more, as well as formatting that data to be as clear as possible.

Twig will be the primary focus of this article. Twig is a template engine that serves two primary purposes in TracCloud:

  • 1. Print variables in text
Personalize your emails and messages. Greet the student by name, let them know what subject they selected in their appointment, what time their appointment takes place, the location, and more. These same variables are also used for purpose #2.
  • 2. Add logic to your text
Modify the email or message based on why it was sent. Add an extra paragraph if Reason X was selected, send a follow-up email after a visit if the student chose Y, prevent an email from being sent on a SAGE referral if Z recommendation was checked, and much more. Rather than creating a generic email for any context, create a dynamic email that changes to match your needs.

Twig (and HTML) are supported in profile emails, welcome messages, email templates, appointment display, and more. Most of the examples listed in this article are for appointment emails or SAGE referrals, but the same concepts apply in all other supported fields. It's also worth keeping in mind that Twig exists outside of TracCloud and there are many resources online for how you can utilize it that will also work here (such as Symfony). This guide likely covers everything you will need, but it doesn't cover everything that Twig is capable of.

HTML will also be used sparingly throughout this article, but without much explanation as it's more ubiquitous than Twig. There are many excellent resources online explaining how to use this markup language, such as W3Schools. HTML is used to adjust font sizes and colors, embed images and videos, and more.

Part 1. Syntax, Terminology, and Essential Knowledge

When reading the wiki or talking to support, you will often see fields like Student.First_Name or Courses.Subject referred to as "Twig tags." To use another term, these are variables. They contain data, it's up to you what you do with that data through Twig. If you're at all familiar with any programming languages, then you likely already know the concepts. This article will provide you with the necessary knowledge to use Twig in TracCloud, regardless of your current knowledge level.

Important: A complete list of Twig tags can be found here. Not all tags can be used in all places, but you can almost always predict what will and won't work in a given location. For example, in the Appointment Confirmation Email, you can expect to use Student, Reason, Subject, Staff tags, etc. Whereas in the Notices on KIOSK, you can only use Center tags. This is because when that message is displayed at the top of an idle kiosk, nothing ties that message to any one Student or Staff record, let alone Registrations, Reasons, etc.

Whenever you're using Twig, you'll see different delimiters being used.

{{ something }} - You would use this to display (i.e., print or echo) the contents of "something."
{% something %} - You would use this to execute something, typically to create conditions (e.g., if statements).
{# something #} - This is a comment. Whatever you write between the hashes will not be displayed. These are handy to make notes for yourself or other admins inside emails and messages.

Here's how those would work in practice. If we sent this to a student named "John," they would receive the message on the right. Notice how the conditional text was handled, and that the comment wasn't shown.


Hi {{Student.First_Name}}!

{% if Student.First_Name == 'Jane' %} 
    Your name is Jane.
{% else %}
    Your name is not Jane.
{% endif %}

{# I never said this example would be realistic #}

Hi John!

Your name is not Jane.


Now here's a more realistic example.


Hi {{Student.First_Name}},

Your appointment has been scheduled for {{Appointment.StartTime}} on {{Appointment.Day}}, {{Appointment.StartDate}} with {{Consultant.FirstLast}}.

{% if Appointment.Online == 1 %}
    Click here to join your appointment: {{Appointment.OnlineLink}}.
{% endif %}

Hi John,

Your appointment has been scheduled for 04:00pm on Thursday, 04/02/26 with Dave Smith.


Part 2. if Statements

The vast majority of the logic you're likely to build with Twig will be if statements. Simply, "if A, do X." You could also do "if A, do X. Otherwise if B, do Y. Otherwise if C, [...]" and so on. For a realistic example, "if the student selected the reason 'Exam Help,' then include the following paragraph" or "if the appointment is online, include the online meeting link."

An if statement always begins with {% if [...] %} and ends with {% endif %}. When building emails and messages, you will be working with Twig tags (variables) in these statements. So the following...

{% if 2 > 1 %}
    two is greater than one!
{% endif %}

{% if 1 == 1 %}
    1 is the same as 1!
{% endif %}

{% if "foo" != "bar" %}
    "foo" is a different word than "bar"!
{% endif %}

...functions just like this. Once again, a list of these tags and definitions are available here.

{% if Appointment.Online == 1 %}
    This is an online appointment, click the following to join....
{% endif %}

{% if Reason.ReasonName == "Writing Support" %}
    Please remember to upload your paper to your appointment. Here's how...
{% endif %}

You can add else and elseif statements before the endif too, to handle alternate cases easily (rather than multiple separate if...endif statements for every condition).

{% if Appointment.Online == 1 %}
    Join Virtually: {{Appointment.OnlineLink}}
{% elseif Appointment.Online == 2 %}
    Accessing your Appointment: Login to TracCloud to view your asynchronous appointment.
{% elseif Appointment.Online == 3 %}
    We will call for your phone appointment at your chosen time.
{% else %}
    In-person location: {{Appointment.Location}}
{% else %}

To check multiple conditions, and and or statements can be used.

{% if Reason.ReasonName == "Academic Coaching" and Student.WatchLists.wl_14 == 'true' %}
    Please remember to bring XYZ to this appointment.
{% endif %}

{% if Reason.ReasonName == "Peer Tutoring" or Consultant.CustomData.cf_123 == 'true' %}
    You have booked an appointment with a Peer Tutor!
{% endif %}

A list of operators can be found in part 4.

Part 3. Working with Arrays

>95% of Twig tags you will work with in TracCloud contain single values, but a very small number of fields are arrays containing multiple values. Most notably, SAGE reasons & recommendations and Multiple Checkbox custom fields.

As an example, take Student.First_Name. This field can only contain one value at any given time. Student.First_Name = Jane, so {{Student.First_Name}} outputs Jane. But how about the Reasons field in SAGE referrals? This is an array that contains "Poor Grades" and "Acceptable Attendance" and "Lack of Focus." If we try to use {{Reasons}}, we'll get an error. That's where we have to take a slightly different approach, using the for tag.

Here's how this works, with an example variable so you can see what it's working with. For each item in the "exampleField" array, it prints the item (and adds a <br> tag to insert a line break).


{% set exampleField = ['a','b','c'] %}
    
{% for item in exampleField %}
    {{item}}<br>
{% endfor %}

a
b
c


Now back to our SAGE example. Remember, Reasons is an array that contains ['Poor Grades','Acceptable Attendance','Lack of Focus'].


    
{% for item in Reasons %}
    {{item}}<br>
{% endfor %}

Poor Grades
Acceptable Attendance
Lack of Focus


You can also check if a value is in an array as an if statement like this. Inversely, you can do not in instead of in to check if a value is not in an array.

{% if 'Poor Grades' in Reasons %}
    Here are some great resources to improve your study habits...
{% endif %}

{% if "Meet with Advisor" in Recommendations %}
    We recommended that you meet with your advisor, here's how to schedule...
{% endif %}

More Twig examples and tag definitions for SAGE emails can be found here.

Part 4. Tips and Tricks

The remainder of this article covers some extra tips and tricks, as well as unique functions that may be of use.

4.1. Special Tags

TracCloud has a few special functions listed below that can be used to prevent an email from sending, CC additional recipients, automatically get special values, and more. More of these functions are available specifically for certain modules, such as SAGE Early Alerts, Success Plans, and Work Plans. Visit the emails/Twig sections of those articles to learn more. The ones listed below are available throughout TracCloud.

{{CalcMissedAppointments(Student.Sequence, Center.ProfileID)}} The student's total number of missed appointments since the date specified in your profile Scheduling Prefs. Uses System Pref date if Profile date is blank.
{{CalcMissedDate(Center.ProfileID)}} Your profile “Calc Missed Appointments Since” date. If this field is blank, this will use your global Calc Missed date instead.
{{setAdditionalCC('address@domain.edu,address2@domain.edu')}} CC additional email addresses, can be used with 'if' statements to make the CC conditional.
{{ GetActiveTermFrom() }} Can be used to get the start date of your current active term(s).
{{ GetActiveTermTo() }} Can be used to get the end date of your current active term(s).
{{ setResultActions('SendEmail', '0') }} Can be used to prevent an email from sending, similar to "#ACTION:DO NOT SEND#" in SAGE emails.
{{ GetDatePlusDays(5) }} Get the current date plus the number of days specified in parentheses
{{ GetDateTimePlusDays(5) }} Get the current date AND time plus the number of days specified in parentheses

4.2. List of Operators

Beyond the basics like == (equals) and != (not equals), there are plenty more operators available depending on what you want to accomplish.

Operator Description True Example
== Equals {% if 1 == 1 %}
!= Does not equal {% if 'a' != 'b' %}
> Greater than {% if 2 > 1 %}
< Less than {% if 1 < 2 %}
in Is contained by (for arrays) {% if 'a' in ['a','b','c'] %}
not in Is not contained by (for arrays) {% if 'z' not in ['a','b','c'] %}
starts with Begins with {% if 'abc' starts with 'a' %}
ends with Concludes with {% if 'abc' ends with 'c' %}

4.3. Filters

Filters can be used to modify or change the data stored in variables. One of the most common examples is using the 'date' filter to modify the format of dates in emails. For example, {{Appointment.StartDT}} would return 2026-01-31 14:00:00, while {{Appointment.StartDT|date("D, F j, h:ia")}} would return "Sat, January 31, 02:00pm." (click here for a list of datetime format codes). A list of some of the supported filters and functions in TracCloud can be found below.

Filter Description Example Output
date Change the format of a date field {{Appointment.StartDT|date("Y-m-d")}} 2026-01-31
lower Changes contents to lowercase {{Student.First_Name|lower}} jane
upper Changes contents to uppercase {{Student.First_Name|upper}} JANE
trim Trim spaces or text from the start and end of a string {{Student.Email|trim('@example.edu')}} jdoe

4.4. Indentation

Twig is not indentation sensitive. Most of the examples in this article use indentation to improve readability, but it will function regardless of it. All three of the examples below will function identically.

    
{% if Appointment.Online == 1 %}
    This is an online appointment!
{% endif %}

{% if Appointment.Online == 1 %}
This is an online appointment!
{% endif %}

{% if Appointment.Online == 1 %}This is an online appointment!{% endif %}

4.5. Streamlining Twig Statements

If you find yourself writing something like this:

{% if Reason.ReasonName == 'X' or Reason.ReasonName == 'Y' or Reason.ReasonName == 'Z' %}

Try using an array instead. Both will work, but the latter is cleaner and easier to update later.

{% if Reason.ReasonName in ['X','Y','Z'] %}

If you're repeatedly checking the same condition, like this:

Your {% if Appointment.Online == '1' or Appointment.CustomData.cf_123 == 'Hybrid Appt' %} online {% endif %} appointment has been scheduled for... 
Location: {% if Appointment.Online == '1' or Appointment.CustomData.cf_123 == 'Hybrid Appt' %} To join, please click... {% endif %}... 
Appointment policies: {% if Appointment.Online == '1' or Appointment.CustomData.cf_123 == 'Hybrid Appt' %} Please remember to... {% endif %}...

Consider setting a variable once and using that instead:

{% if Appointment.Online == '1' or Appointment.CustomData.cf_123 == 'Hybrid Appt' %}
    {% set online = true %}
{% else %}
    {% set online = false %}
{% endif %}

Your {% if online %} online {% endif %} appointment has been scheduled for... 
Location: {% if online %} To join, please click... {% endif %}... 
Appointment policies: {% if online %} Please remember to... {% endif %}...

This one is more minor, but in most cases instead of writing this:

{% if Appointment.Location != '' %}

You can write the following. This will return true if that field is not false, blank, or 0.

{% if Appointment.Location %}

Part 5. Getting Help

If you're a primary SysAdmin for your TracCloud instance and you need some help with Twig or HTML, feel free to reach out to us. Scroll all the way to the top of this page and click the "Support" tab to visit our helpdesk.