We've integrated our platform with Bootstrap 5 to make it easier to build beautiful, custom jobs in the Code Editor. This article describes how to use the Bootstrap 5 framework when building a job in Appen.
This is a job that uses Bootstrap extensively:
And here’s the same job, with Bootstrap elements called out:
Fig. 2: Job with Bootstrap elements called out
Here's a preview of the entire code for this job:
CML:
<cml:radios label="Ask question here:" validates="required" gold="true">
<cml:radio label="First option" value="first_option" />
<cml:radio label="Second option" value="second_option" />
</cml:radios>
<!--Bootstrap 5 uses .row instead of .row-fluid. Columns use .col-* instead of .span* -->
<div class="row">
<!--First column spanning 4 of 12 grid columns -->
<div class="col-4">
<h4>View the social media post:</h4>
<br/>
<!--Button uses .btn-lg (was .btn-large in Bootstrap 2) -->
<a href="{{url}}" class="btn btn-primary btn-lg">Click here</a>
</div>
<!--Second column spanning 8 of 12 grid columns -->
<div class="col-8">
<cml:radios label="What is the sentiment of this post?" name="sentiment" validates="required">
<cml:radio label="Positive" value="positive"/>
<cml:radio label="Neutral" value="neutral"/>
<cml:radio label="Negative" value="negative"/>
</cml:radios>
<!--Bootstrap Icons replace Glyphicons. Use -->
<a tabindex="0" class="positive_tip" role="button" data-bs-trigger="hover focus" data-bs-toggle="popover" data-bs-title="Positive" data-bs-html="true" data-bs-placement="bottom">
Positive
<i class="bi bi-info-circle"></i>
</a>
<a tabindex="0" class="neutral_tip" role="button" data-bs-trigger="hover focus" data-bs-toggle="popover" data-bs-title="Neutral" data-bs-html="true" data-bs-placement="bottom">
Neutral
<i class="bi bi-info-circle"></i>
</a>
<a tabindex="0" class="negative_tip" role="button" data-bs-trigger="hover focus" data-bs-toggle="popover" data-bs-title="Negative" data-bs-html="true" data-bs-placement="bottom">
Negative
<i class="bi bi-info-circle"></i>
</a>
</div>
</div>JavaScript:
// Bootstrap 5 does not use AMD modules or require().
// jQuery is no longer required by Bootstrap itself.
// Initialize popovers using the Bootstrap 5 Popover API directly.
require(['jquery-noconflict'], function (jQuery) {
var $ = window.jQuery;
var positiveTip = document.querySelector('.positive_tip');
new bootstrap.Popover(positiveTip, {
html: true,
placement: 'bottom',
trigger: 'hover focus',
title: 'Positive:',
content: '<p>Positive sentiment messages include: <ul><li>Excitement about the topic of the post</li><li>Offering a strong recommendation for the product</li><li>Expressing praise, or drawing an extremely favorable comparison</li></ul></p>',
});
var neutralTip = document.querySelector('.neutral_tip');
new bootstrap.Popover(neutralTip, {
html: true,
placement: 'bottom',
trigger: 'hover focus',
title: 'Neutral:',
content: '<p>Neutral sentiment messages include: <ul><li>Factual statements with no emotional tone</li><li>Posts that neither praise nor criticize</li></ul></p>',
});
var negativeTip = document.querySelector('.negative_tip');
new bootstrap.Popover(negativeTip, {
html: true,
placement: 'bottom',
trigger: 'hover focus',
title: 'Negative:',
content: '<p>Negative sentiment messages include: <ul><li>Complaints or expressions of frustration</li><li>Strongly unfavorable comparisons</li></ul></p>',
});
});
How to add the Grid Layout and Button:
Bootstrap 5 uses a revised grid system. Read up on Bootstrap 5's Grid System and Buttons before getting started.
Create Bootstrap's grid system for the job interface. The grid contains a maximum of 12 top level columns.
<div class="row">
The first column spanning 4 columns is created with the class col-4. Create a button link using the class btn and size it with btn-lg:
<div class="col-4">
<h4>View the social media post:</h4>
<br/>
<a href="{{url}}" class="btn btn-primary btn-lg">Click here</a>
</div>The second column spans 8 columns, and is created with the class, 'span8'.
<div class="col-8">
<cml:radios label="What is the sentiment of this post?" name="sentiment" validates="required">
<cml:radio label="Positive" value="positive"/>
<cml:radio label="Neutral" value="neutral"/>
<cml:radio label="Negative" value="negative"/>
</cml:radios>
</div>
</div>
How to add the Icons:
Bootstrap 5 no longer bundles Glyphicons. The platform now supports Bootstrap Icons, a separate icon library included in the environment.
Add a Bootstrap icon using the <i> tag with the bi base class and the specific icon name:
<i class="bi bi-info-circle"></i>
Browse the full icon set at icons.getbootstrap.com.
How to add the Popovers:
Bootstrap 5 popovers work differently from earlier versions. The plugin is no longer loaded via require(['bootstrap-popover']). Bootstrap 5 is bundled with the platform, and popovers are initialized using the bootstrap.Popover JavaScript API directly.
Create popover trigger elements in CML using accessible markup with a custom class name (e.g. positive_tip):
<a tabindex="0" class="positive_tip" role="button">
Positive <i class="bi bi-info-circle"></i>
</a>
In the JavaScript section, initialize each popover using new bootstrap.Popover(). The MooTools Window.implement workaround from earlier versions is no longer required:
require(['jquery-noconflict'], function (jQuery) {
var positiveTip = document.querySelector('.positive_tip');
new bootstrap.Popover(positiveTip, {
html: true,
placement: 'bottom',
trigger: 'hover focus',
title: 'Positive:',
content: '<p>Your popover content here.</p>',
});
});
For full popover documentation, see: Bootstrap 5 Popovers.
Migrating from Bootstrap 2
If you have existing jobs built with Bootstrap 2.3.2, the following changes are required:
| Element | Bootstrap 2 (old) | Bootstrap 5 (new) |
| Fluid row | .row-fluid |
.row |
| Column |
.span4, .span8
|
.col-4, .col-8
|
| Large button | .btn-large | .btn-lg |
| Info icon | <i class="icon-info-sign"/> | <i class="bi bi-info-circle"></i> |
| Load popover plugin | require(['bootstrap-popover']) |
Not needed — Bootstrap 5 is bundled |
| Initialize popover | $('.el').popover({...}) | new bootstrap.Popover(el, {...}) |
| MooTools workaround | Required |
Not required |