Table of Contents | ||||
---|---|---|---|---|
|
...
Other tag examples: ul, img, div, span
We introduce a few other tags and discuss how HTML code for these tags can be generated using some of the predefined predicates in the html.pl
file. These examples should provide you with a general understanding of how you can generate HTML code for a variety of HTML elements.
ul tag
Displaying lists is a practical feature when you want to show a recipe and its associated ingredient list. The most basic way to do this is to use the unordered list ul
and list item li
tags. Here’s a simple example of what the HTML code would look like:
...
This combined query will generate our example HTML code and return it as value in the Html
variable.
...
img tag
...
div tag
Code Block |
---|
% card text
txtHtml('<div class="card-body"><p class="card-text">~a</p></div>').
txtHtml(Txt, Html) :- txtHtml(Template), applyTemplate(Template, Txt, Html). |
...
span tag
'<span style="font-family:Roboto;">',
...
By means of these and generate with the rule. The HTML code is represented in Bootstrap format, which is also clearly illustrated by examples below or on Bootstrap's documentation website (Bootstrap Documentation).
Note |
---|
Prolog Advice: To manipulate strings and atoms in Prolog it is useful to look at documentation of the following built-in functions: atomic_list_concat, atom_concat, string_concat, append, and maplist here: https://www.swi-prolog.org/. The predicate applyTemplate is a defined predicate that will be explained below. |
...
Code Block | ||
---|---|---|
| ||
page(c10, _, Html) :- % Condition for when to show this page CONDITION X, % Constructing HTML page atomic_list_concat(['<div class="alert alert-light"><center></br><h1>Hello!</br></br>','I am ~a</h1></br></br></center></div>'], Template), % Get the bot's name if it has one; other call it 'your assistant' (agentName(Name) -> N = Name ; N = 'your recipe selection assistant'), applyTemplate(Template, N, Body), % Create the HTML page html(Body, Html). |
A Quick Bootstrap Conceptual Walkthrough
Bootstrap is a useful framework for working out a display, but may not be so intuitive in combination with Prolog. We provide a short walkthrough here to explain things for you.
Let’s consider you would like to display a certain lay-out with three images side-by-side. The first step you would take is to check whether such a lay-out is specified in Bootstrap. ‘Card decks’ might be a nice option, so we first look into the code that is involved:
...
Adding a chatbox to your page layout for testing purposes
The speech interface is fitting to the context of a user in a kitchen, but not always feasible for testing. It may take additional time for the system to process speech input, you may be in a noisy environment, and there may be speech recognition failures. Hereby a pointer to easily enable a textbox to be rendered for input.
In the html.pl
file, where you format the pages to render during the conversation, for each of the pages that you may display at any point in the conversation add the following code:
Code Block |
---|
A chatbox can be added for using text instead of speech for input by adding
<div class="text-center"><p class="chatbox mx-auto"></p></div>, for example,
to the footer. |
Using and Understanding the code in html.pl
A Quick guide to using Bootstrap components not defined in html.pl
We briefly discuss an example on how to use the code in html.pl
yourself with Bootstrap components that you might want to use but have not yet been introduced yet. To that end, suppose that you would like to create a lay-out with three images side-by-side. The first step you could take is to check which components Bootstrap offers to create such a lay-out. It turns out that a card deck might just be what you were looking for. It is advertised as something you would use when you “Need a set of equal width and height cards that aren’t attached to one another? Use card decks.” Bootstrap also provides the HTML template code as an example of how to use it. This is what that looks like:
Code Block |
---|
<div class="card-deck"> <div class="card"> <img class="card-img-top" src=".../100px200/" alt="Card image cap"> <div class="card-body"> <h5 class="card-title">Card title</h5> <p class="card-text">This cardis hasthe supporting text below as a natural lead-in to additional content.</p> <pfirst card.</p> </div> </div> <div class="card"> <img class="card-img-texttop"><small src="..."> <div class="textcard-muted">Last updated 3 mins ago</small><body"> <h5 class="card-title">Card title</h5> <p class="card-text">This is the second card.</p> </div> </div> <div class="card"> <img class="card-img-top" src=".../100px200/" alt="Card image cap""> <div class="card-body"> <h5 class="card-title">Card title</h5> <p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.</p> <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p> </div> </div> </div> |
What we want to achieve, is to render a page with the HTML code, but with a dynamic input of images. The trick is to break this down into fragments. First, we want to render a given image. In the HTML, we see that each of the three images are defined as separate cards. We will now use Prolog to generate the HTML for such a card, using a given picture URL. The aim is to connect in a single string the static HTML code and the image URL (which differs according to the context of the conversation). Let’s work with the good old Pasta Aglio URL for this example. We will define a predicate ‘imgCard’, with an arity of 1 and an arity of 2. We will give it once as a fact, specifying the HTML code:
Code Block |
---|
imgCard('<div class="card"><img class="card-img-top" src="~a" alt="Card image cap"></div>'). |
Note that the HTML is copied, with a replacement of the contents of ‘src’, in the form of ‘~a’ which is a placeholder for the image URL. This is needed in order to dynamically add this information. We will do this with the following rule:
Code Block |
---|
imgCard(Image, Html) :- imgCard(I), format(atom(Html), I, [Image]). |
In this rule, the Image
variable is the input and holds the URL of the image, whereas the Html
variable is the output HTML code for this card. In the body of the rule, the imgCard/1
is queried to retrieve the HTML code that we already specified. Then, the URL is placed at the location with `~a' in this HTML code (in the Image
variable), using the format/3
predicate.
We can now use the imgCard term to render each of the three images. For the complete display, we will combine them in the broader ‘card-deck’ option, like in the example HTML we got from bootstrap. We will do this using a self-defined Prolog term, with as input the text, button text and the three images, and as output the HTML code to render. Within this term, we will start specifying the main template, and then collect the images:
Code Block |
---|
myThreeImagesPage(Txt, Button, Image1, Image2, Image3, Html) :-
Template='<div class="card-deck">~a</div>',
imgCard(Image1,I), imgCard(Image2,I2), imgCard(Image1,I3),
atom_concat(I,I2,II), atom_concat(II,I3,III),
format(atom(Card), Template, [III]), html(Card, Html). |
Note that atom_concat is used to append the different HTML snippets for each of the images. Format is then used to plug in the HTML code where the `~a' has been specified in the Template variable (as was done for the imgCard).
The current term will display three given images on the screen. Of course, you need to make sure that the right image URLs can be displayed during the conversation, which you can do using Prolog facts in recipes.pl
.
Other Add-ons You Can Try
Info |
---|
Note that these add-ons use variable names, and functions from our version of the code, and may not align with the names you use. Make sure everything matches up properly! These are just examples, you can add anything your heart desires. |
Adding a chatbox to your page layout for testing purposes
The speech interface is fitting to the context of a user in a kitchen, but not always feasible for testing. It may take additional time for the system to process speech input, you may be in a noisy environment, and there may be speech recognition failures. Hereby a pointer to easily enable a textbox to be rendered for input.
In the html.pl
file, where you format the pages to render during the conversation, for each of the pages that you may display at any point in the conversation add the following code:
Code Block |
---|
A chatbox can be added for using text instead of speech for input by adding
<div class="text-center"><p class="chatbox mx-auto"></p></div>, for example,
to the footer. |
...
is the third card.</p>
</div>
</div>
</div> |
How do we break this code down into pieces that we can (already) manage? We first scan the code for the HTML tags that are used in it. We find that the div
tag is often used (with the classes "card-deck"
, "card"
, and "card-body"
). We also find that the img
tag is used as well as some variants of the <h5>
and <p>
tags with specific card-related classes added. We note that for each of these tags we already have the tools to generate them in Prolog. We can use the div/4
and img/4
predicates for the former tags and can use our strategy to quote basic HTML elements for the h5
and p
elements (you can also introduce new predicates for these tags in combination with a class attribute if you like but we prefer to keep it simple here).
Now we have established that all the basic ingredients are available, the next step in our recipe is to create the separate parts of the HTML code by - in a sense - looking from the inside out. We first will generate the elements that are most embedded and then use those to build the elements in which they are directly embedded.
First, we want to render a given image. In the HTML, we see that each of the three images are defined as separate cards.
We will now use Prolog to generate the HTML for such a card, using a given picture URL. The aim is to connect in a single string the static HTML code and the image URL (which differs according to the context of the conversation).
Code Block |
---|
imgCard('<div class="card"><img class="card-img-top" src="~a" alt="Card image cap"></div>'). |
Note that the HTML is copied, with a replacement of the contents of ‘src’, in the form of ‘~a’ which is a placeholder for the image URL. This is needed in order to dynamically add this information. We will do this with the following rule:
Code Block |
---|
imgCard(Image, Html) :- imgCard(I), format(atom(Html), I, [Image]). |
In this rule, the Image
variable is the input and holds the URL of the image, whereas the Html
variable is the output HTML code for this card. In the body of the rule, the imgCard/1
is queried to retrieve the HTML code that we already specified. Then, the URL is placed at the location with `~a' in this HTML code (in the Image
variable), using the format/3
predicate.
We can now use the imgCard term to render each of the three images. For the complete display, we will combine them in the broader ‘card-deck’ option, like in the example HTML we got from bootstrap. We will do this using a self-defined Prolog term, with as input the text, button text and the three images, and as output the HTML code to render. Within this term, we will start specifying the main template, and then collect the images:
Code Block |
---|
myThreeImagesPage(Txt, Button, Image1, Image2, Image3, Html) :-
Template='<div class="card-deck">~a</div>',
imgCard(Image1,I), imgCard(Image2,I2), imgCard(Image1,I3),
atom_concat(I,I2,II), atom_concat(II,I3,III),
format(atom(Card), Template, [III]), html(Card, Html). |
Note that atom_concat is used to append the different HTML snippets for each of the images. Format is then used to plug in the HTML code where the `~a' has been specified in the Template variable (as was done for the imgCard).
The current term will display three given images on the screen. Of course, you need to make sure that the right image URLs can be displayed during the conversation, which you can do using Prolog facts in recipes.pl
.
Defining new predicates for generating HTML elements
applyTemplate('Template String with ~a where you want to insert atom', Atom to Insert, Return Variable).
...