In Planado you can set up your print layouts. This way your layouts can have a view that you want. Custom print layouts allow you to select an input format of PDF and HTML. the


The print layout is edited through an HTML file. It uses Liquid as a markup language. You can find its documentation on the official website.


The default print layout

You can use the default print layout before adding your custom print layouts. To see what it looks like, open any job and click the print button.


Print a job


After that, Planado will print your job to a PDF file using the default print layout.


Default job print layout


We advise you to use the default print layout as an example for your own future layouts. You can find its file on the Settings → Printing page. To download the default layout HTML file, click the Default layout and select Download.



Download the default print layout


After that, the HTML file of the default print layout will be downloaded to your computer. You can open it in an HTML editor of your choice. In this example, we will use Notepad++.


Currently, the default layout cannot be modified.


Default print layout

Substitutions

Print layouts use different substitutions to access different Planado entities. In Liquid language, curly braces are used to access variables. Because of that, to access Planado entities we also use curly braces. For example, {{ job.template.name }} will print out your job template name. In the same way, you can access canned words like “Job". Here we will list most of the substitutions used in the print layouts. 


  • job — the word "job";
  • job.serial_no — job serial number;
  • job.status — job current status;
  • job.template — job template;
  • template — the word "Template";
  • type — the word "type";
  • job.type.code — job type;
  • scheduled_at — the word "scheduled at";
  • job.scheduled_at — job scheduled date and time;
  • duration — the word "Duration";
  • job.scheduled_duration — job planned duration;
  • en_route_at — the word "En route";
  • job.en_route_at — job en route date and time;
  • started_at — the word "Started"
  • job.started_at — job start date and time;
  • finished_at — the word "Finished";
  • job.finished_at — job finished date and time;
  • created_at — the word "Created";
  • job.created_at — job creation date and time;
  • job.creator.name — the name of a user who created the job;
  • assignee — the word "Assignee";
  • job.assignee — job assignee if it was assigned to an individual worker;
  • job.team — job assignee if the job was assigned to a team;
  • description — the word "Description";
  • job.description — job description;
  • address — the word "Address";
  • job.address.full — job address;
  • client — the word "Client";
  • job.client.name — name of job client;
  • site — the word "Site";
  • job.site.name — name of job site;
  • resolution — the word "Resolution";
  • job.resolution.name — the job resolution;
  • job.resolution.comment  the comment to the job resolution;
  • external_id — the word "External ID";
  • job.external_idjob external ID;
  • contacts — the word "Contacts";
  • contact.name — the name of the job contact;
  • contact.value — the phone number of the job contact;
  • field.name — the field name (for custom and report fields)


All these substitutions can be found in the default print layout. 


Let's also look at the Shopify Liquid tools.


Shopify Liquid operators

you Shopify Liquid is a markdown language. It allows to dynamically set layout content depending on your job.


The output operators:

  • {{ }}:  outputs variable value.

    {{ job.serial_no }}  {{ job.scheduled_at | datetime }} 

    In this example, it will output the job serial number and job scheduled date.

  • {% %}:  Is used to control logic and cycles. For example, it is used with the if operator.

    {% if job.type %}   <div class="field"> ... </div> {% endif %} 

    In this example, the <div> element will show up only when a job type is present.


1. if —  conditional expressions

The if operator is used to set up conditions for information output in a print layout. The information will be shown only if the conditions from the if operator are met.

  • Synthax:

    {% if condition %}    // The code runs if the condition is met
        ...
    {% elsif condition2 %}// Code runs if 1st condition is false and 2nd is true

        ...
    {% else %} // Code runs if all previous conditions are false

        ...
    {% endif %}
  • Example:  check if the client's address is filled

    {% assign address_present = job.address.formatted | filled? %} 
    {% if address_present %}
        <div class="field">
    <label>{{ 'address' | translate }}</label>
    <span class="value">
    <span class="multiline-text">{{ job.address.full }}</span>
         </span>
    </div>
    {% endif %}
  • Using eslif: checking if a worker or a team is assigned to the job.

          <div class="field">
        <label>{{ 'assignee' | translate }}</label>
            {% if job.assignee %}
                <span class="value">{{ job.assignee }}</span>
            {% elsif job.team %}
                <span class="value">{{ job.team }}</span>
            {% else %}
                <span class="value empty-value">{{ 'empty' | translate }}</span>
            {% endif %}
    </div>

2. for - cycles:

For operator is usually used with data arrays. For example, to output job report fields. 

  • Syntax:

    {% for item in items %} // Code will run for every item in the "items" array
    ...
    {% endfor %}
  • Пример:  Вывод контактов:

      {% for contact in job.filled_contacts %}
        <div class="field contact">
    <label>
                {% if forloop.first %}
                    {{ 'contacts' | translate }}
                {% endif %}
            </label>
    <span class="value">
            {{ contact.value }}{% if contact.name and contact.value %}, {% endif %}
                {{ contact.name }}
            </span>
    </div>
    {% endfor %}
Here, the cycle goes through all elements of the contacts array to output their names and phone numbers.

3. case - condition selection

As well as if, the case operator is used to set conditions.

Как и if используется для указания условий.

  • Syntax:

    {% case variable %}
    {% when value1 %} // Code runs if variable is equal to "value1"
    {% when value2 %}// Code runs if variable is equal to "value2"
    {% else %} // Code rund if variable is not equal to any conditions
    {% endcase %}
  • Example:  settings conditions for different field types.

          {% for field in job.report_fields %}
        <div class="field">
            <label>{{ field.name }}</label>
            {% case field.field_type %}
                {% when 'input' %}
                    ...
                 {% when 'action' %}
                    ...
                {% when 'checkbox' %}
                    ...
                {% else %}
                    ...
            {% endcase %}
        </div> {% endfor %}
In this case, conditions for each field type are set separately.


Basic operators:

  • ==:  checks equality

      {% if job.description == "" %}
       <span class="value empty-value">{{ 'empty'| translate }}</span>
     {% endif %}

    In this example, an empty value will be shown only when the job description is empty.

  • !=:  checks for inequality

     {% if job.resolution.comment != "" %}
       <span class="value"> ... </span>
    {% endif %}
In the example resolution comment will be displayed only when it is not empty.

In the same way, you can use other basic operators:
  • >:  greater than;

  • <:  less than;

  • >=:  greater than or equal;

  • <=:  less than or equal.


Logical operators:

  • and: logical AND: is true only when both conditions are met

    {% if job.template == "Delivery" and job.assignee.name == "John Smith" %} John Smith's delivery {% endif %}    
In the example, the condition is met only when the template "Delivery" is used and the assignee is John Smith.
  • or:  logical OR is true when either or all conditions are met.

    {% if job.assignee or job.team %} ... {% endif %}    
A value is displayed when an assignee or a team is assigned to the job.
  • not:  logical NOT: reverses condition from true to false and the other way around.

    {% if not job.description %} ... {% endif %}    

Filters:

  • empty: checks if the variable has an empty value.

    {% if job.resolution.comment | empty %} ... {% endif %}    
  • filled:  checks if the variable does not have an empty value.

    {% if job.description | filled %} ... {% endif %}    

Other filters:

  • datetime: changes date format to a readable one. Contains time.

  • truncate: cuts down a string to a specified length.

  • translate:  translates string to your Planado language.


Let's look through different ways you can modify a print layout.


The print layout from the example you can find in the attachment to this article.



Changing company logo

You can change the Planado logo to your own by editing the print layout. To do so, you need to use the custom-logo field.


Default custom-logo CSS settings


First, you need to convert your company logo to base64 format. You can use an online converter to do so. After that, you can use the generated base64 code in the print layout.


On the left, the company logo is in the PNG format, on the right the same logo is in the base64 format.


Change the logo tag to the custom-logo tag in the print format body.


On the left is the default print layout, and on the right is the print layout with a custom-logo added. 


Now you can add the image into the <div> element. As source (src) we will use the logo in the base64 format.



The logo before and after the transformation


After that, you can set the logo dimensions for the print layout. The logo will look better if it has a height and a width of around 100-200px. The new dimensions should be a multiple of the original dimensiones. For example, if you have a logo with 1920x1080px, you can set its resize to 192x108px. In our example the original size was 1200x1200px, so we will set its resize to 120x120px.


The added logo image


To upload your new print layout file, go to the Settings → Printing page in your Planado and click the Add layout button.


Add a new layout


In the opened window enter your print layout name and upload your HTML file of the print layout. Depending on your needs you can select either PDF of HTML as an output format. In this example, we will use the PDF format.


Upload a new print layout


To check how your new layout looks, open a job, click the print button, and select the newly added layout.


Print a job using your new layout


Your job will be printed using your new print layout.


A printed job with a new logo


In the file, your logo will be used instead of the Planado one. 


If you need to tweak the logo size or modify it some other way, you can do that in the HTML file and then re-upload your print layout.


Change print layout file


Adding photos to a print layout

By default, photo field values are displayed as file names. If you want to display actual photos instead of them, you need to specify it in the print layout.


File names in the photo fields


The conditions to display photo fields are set in the report fields part of the print layout.

{% when 'image' %}
{% if field.value == empty_list %}
<span class="value empty-value">{{ 'empty' | translate }}</span>
{% else %}
<span class="value image-value">
{% for image in field.value %}
{{ image.name }}{% unless forloop.last %}, {% endunless %}
{% endfor %}
</span>
{% endif %}

Here we can see that if a photo field has an image, it will show only its name {{ image.name }}. To display an actual image, we need to change that part.


 {% when 'image' %}

{% if field.size > 0 and field.filled %}
{% for image in field.value %}
{{image}}
{% endfor %}
{% endif %}

Now instead of a file name an actual image is displayed. However, it is displayed in its actual size.


Printed job with a photo in its actual size


Usually, you do not need photos with such a large size. Fortunately, we can resize images using the resize filter in the {{ image }} operator. In our case, images have 1080x1920px dimensions. Because of that, we will use the 108x192px images in our print layout. We will also add a space between photos.

 {% when 'image' %}
            
              {% if field.size > 0 and field.filled %}
              {% for image in field.value %}
                 
             
         {{image | resize: 108, 192}} &nbsp;
         
         
        
                {% endfor %}
              {% endif %}

Resized photos in a printed job with a space between them


In a newly created layout photos have adequate size and a space between them.


We can also add a counter that will transfer photos to a new line if a line has more than 4 photos. In this case, we will use two extra <div> classes: image-row and image-wrapper.

  .image-row {
display: flex;
flex-wrap: wrap;
margin-bottom: 5px;
}

.image-wrapper {
flex: 1 1 calc(33.33% - 5px);
margin-right: 5px;
margin-bottom: 5px;
}

.image-wrapper:nth-child(3n) {
margin-right: 0;
}

Now every image is placed in a separate <div>, this way we do not need an extra space between photos.

{% when 'image' %}
{% if field.size > 0 and field.filled %}
{% assign image_count = 0 %}
{% for image in field.value %}
{% if image_count == 0 %}
<div class="image-row">
{% endif %}
<div class="image-wrapper">
{{ image | resize: 108, 192 }}
</div>
{% assign image_count = image_count | plus: 1 %}
{% if image_count == 3 %}
</div>
{% assign image_count = 0 %}
{% endif %}
{% endfor %}
{% if image_count != 0 %}
</div>
{% endif %}
{% endif %}


In this example, every image in a photo field increases the image_count counter. When image_counter reaches the value of 3, it moves an image to the next line and resets itself. 


This is how a printed job looks like when it has five photos in one photo field.


vA printed job with five images in one photo field

You can find this print layout in the attachment to this article.


HTML as an output format

You can change your print layout output format from PDF to HTML. HTML printed job is easier to edit in a text editor like Microsoft Word or OpenOffice Writer. If you want to edit your printed job after downloading it, you should use HTML as an output format. 


To change the output format:

  1. Open the Settings → Printing page
  2. Select a print layout;
  3. Select HTML as an output format and click the Save button.

Change output format to HTML


After that, this layout will use HTML as an output format when printing jobs.


A job printed in the HTML format


You can edit this file using a text editor of your choice.


If you need any help or have any questions regarding print layouts, feel free to contact us at support@planado.app or on the support portal.