The Now Platform® Washington DC release is live. Watch now!

Help
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
SlightlyLoony
Tera Contributor

Now that you're expert on Jelly's two phases, and the differences between Jelly and JavaScript variables, you're probably thinking "Hey, my Jelly education is done! Where's my diploma?"

Well, not so fast, grape jelly breath. There's still a lot to learn!

First, a commenter asked an important question, which I managed to forget to address: "What's the whole point of the multi-phase Jelly system, anyway?" Answer: it's all about performance. There isn't any other reason for it. Because the phase 1 output is cached (in memory), there is potentially (exactly how much varies from page to page) quite a large amount of work that is done just once, instead of every time a page is requested.

Next, let's look at an example that illustrates a few things I want to talk about:


<?xml version="1.0" encoding="utf-8"?>
<j:jelly>
<g:evaluate>
var title = 'Users for ' + gs.getUser().getFirstName() + ' ' + gs.getUser().getLastName();
title;
</g:evaluate>
<g2:evaluate>
var users = new GlideRecord('sys_user');
users.query();
</g2:evaluate>


$[jvar_title]
<j2:while>

User: ${users.first_name} ${users.last_name}
</j2:while>
</j:jelly>

Oh, my. Where should I start? If you run this little gem, you'll get a gloriously blank screen. Absolutely nothing is displayed. Why is this? We'll tackle it one item at a time. First, consider these parts:

<g:evaluate>
var title = 'Users for ' + gs.getUser().getFirstName() + ' ' + gs.getUser().getLastName();
title;
</g:evaluate>


$[jvar_title]

We thought we were being soooo clever here! In the evaluate tag, we're building the title for our page. We're doing it in Phase 1 because it only needs to be done once for any given user. But...look at the last line, where we're actually rendering the title into HTML. There we used the JEXL expression $[jvar_title] — and those square brackets tell it to evaluate the JEXL in Phase 2. In Phase 2, the jvar_title variable isn't even defined, and so it has nothing in it (which is exactly what renders: nothing). Oops. There are two possible fixes for this that work equally well. The first fix is to simply change the JEXL expression to ${jvar_title} so that it renders on Phase 1. The second is slightly trickier: there's an attribute you can add to the evaluate expression to tell Jelly to copy the value of the variable calculated in Phase 1 to the same variable in Phase 2. That would look like this:

<g:evaluate>
var title = 'Users for ' + gs.getUser().getFirstName() + ' ' + gs.getUser().getLastName();
title;
</g:evaluate>


$[jvar_title]

Now if you run it, you'll see a title — but nothing else. So what else did we do wrong? Take a look at these pieces of the puzzle:

<g2:evaluate>
var users = new GlideRecord('sys_user');
users.query();
</g2:evaluate>

<j2:while>

This is an example of phase mis-match — the j2:while tag gets evaluated in Phase 2, but the JEXL expression ${users.next()} is evaluated in Phase 1. The JavaScript variable users was defined in the g2:evaluate tag, so in Phase 1 it doesn't even exist for the JEXL expression to evaluate. What ends up happening is that in Phase 1 the while tag gets turned into this: — and in Phase 2 the test always returns false. That means that the inside of the while loop never executes. Bummer, dude. The fix is easy: change the JEXL test expression to $[users.next()] so that it evaluates in Phase 2. Now when you run it...it's still screwed up. But slightly less so: now we've got a column of "User:" down the left side of our screen. Now what? Maybe by now you can spot the problem:


User: ${users.first_name} ${users.last_name}

It's another Phase mixup — we've used a Phase 1 JEXL expression to render the first and last name — but the script that queries the database to retrieve the user records is running in Phase 2. Again, the fix is simple: change the JEXL expressions to Phase 2, like $[users.next()]. Now when you run it...it works! A nice, ugly, dumb report. But it works!

If it seems like I'm harping on this topic of Phase 1/Phase 2 mixups, well, it's because I am — and because it's one of the more common sources of problems with Jelly templates. When I build a Jelly template and the danged thing doesn't work on the first try (that would be every time), then the first thing I do is to look for some place where I got the Phases wrong. Maybe it's just me — could easily be! But you might want to check for those mixups in your own Jelly templates, too...

3 Comments