Register to get access to free programming courses with interactive exercises

JavaScript HTML: Preprocessor Pug

Pug allows you to use JavaScript to add logical expressions to a template. In the SASS course, we looked at many options for creating additional logic like variables, functions, loops, and conditional constructs.

The JavaScript inside Pug allows you to do the same but with slightly different syntax and features. It is a crucial part of working with the templating tool, allowing you to reveal it one hundred percent.

If you are not familiar with how JavaScript works and looks, you can take the Programming fundamentals course. It will teach you the basics of the language.

We can divide all JavaScript code inside the preprocessor into three main groups:

  1. Buffered code
  2. Unescaped buffered code
  3. Unbuffered code

These words are scary, but the concepts are simple. Let us look at each of them separately.

Unbuffered code

A distinctive feature of unbuffered code is that it is not output into the final HTML. Any code in this style will not add a single line to the final code. Its purpose is to create additional logic within the preprocessor. These can be variables, arrays, loops, and so on. To create unbuffered code, we use the - symbol and add JavaScript code.

Create a variable with text and add it to the paragraph:

- const title = "Hexlet Training Programs"; // JavaScript code

      h1 #{title}
<div class="container">
  <div class="row">
    <div class="col-12">
      <h1>Hexlet training programs</h1>

Interpolation of variables and expressions

The h1 #{title} construct helps to output the variable value in the last example. The #{} construct outputs the contents of a variable or an expression as a string:

- const one = 1;
- const two = 2;
- const action = "plus";

  | #{one} #{action} #{two} = #{one + two}
<div class="calculation">1 plus 2 = 3</div>

There is one weird part of interpolation: HTML tag escaping. Instead of escape symbols, we use special mnemonic symbols. It works that way for security reasons: if you output the tags as is, there is a risk that someone can insert unwanted tags:

- const html = "<p>Paragraph text</p>";

  | #{html}
<div class="result">
  &lt;p&gt;Paragraph text&lt;/p&gt;

Pug provides an option to change this behavior and output unescaped characters. We use the !{} construct for this, but be careful; using this code is a potential problem, especially when receiving data from the user:

- const html = "<p>Paragraph text</p>";

  | !{html}
<div class="result">
  <p>Paragraph text</p>

Buffered code

If the unbuffered code doesn't interact directly with the layout, the task of the buffered code is to process the JavaScript and insert the layout result.

It is much easier to understand the difference in practice. Buffered code starts with the = symbol:

  p= 2 + 2
<div class="plus">

As with interpolation, Pug escapes all HTML when using the buffered output for security:

  p= "<span>Hello</span>, Hexlet"
<div class="buffer">
  <p>&lt;span&gt;Hello&lt;/span&gt;, Hexlet</p>

Unescaped buffered code can undo this effect. Like with interpolation, you need to insert the ! symbol. Although this action is possible, it's worth reiterating that using unescaped output is a bad practice because it creates potential security problems:

  p!= "<span>Hello</span>, Hexlet"
<div class="buffer">
  <p><span>Hello</span>, Hexlet</p>

At first glance, there's no significant difference between buffered and unbuffered code. On the one hand, both methods allow you to add JavaScript logic to existing code, but there is a difference. Buffered code must first get the result, and only then will it be output. We can execute unbuffered code at any convenient time or not execute it at all.

  • Unbuffered code is convenient when creating functions, arrays, and objects
  • Buffered code is most often used when creating single-line functions or strings that consist only of JavaScript code

Additional assignment

Using the knowledge you've gained from the Programming fundamentals course, create a variable with a counter and, using a loop, increment it by two. Output the results as a list. Choose the number of iterations yourself. Determine where the buffered and unbuffered code will be.

Let us observe a sample result:


Hexlet Experts

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

About Hexlet learning process

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
hours of theory

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing:">Bookmate</span>
<span class="translation_missing" title="translation missing:">Healthsamurai</span>
<span class="translation_missing" title="translation missing:">Dualboot</span>
<span class="translation_missing" title="translation missing:">Abbyy</span>
Suggested learning programs
Layout with the latest CSS standards
5 months
from scratch
under development
Start at any time

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.