...
...
...
Table of Contents | ||||
---|---|---|---|---|
|
Having our agent build HTML
An important facet of our conversational agent is the visuals that accompany it. While it looks a bit complicated it is nothing above visual support. While the way in which visuals are modelled in the agent may look complicated, there is nothing that goes far beyond basic HTML. We utilize a combination of Prolog, HTML and bootstrap Bootstrap to generate these dynamic webpages. Prolog rules are how we used to add a condition to a webpage (i.e. this webpage X is shown when Clause X Y is true. Within this same rule ). By means of these Prolog rules, we generate our HTML code. The HTML code is treated as an a Prolog atom, essentially a string, that we manipulate with Prolog and return generate with the rule. The HTML code is done represented in bootstrap Bootstrap format, which is also clearly depicted in illustrated by examples below or on bootstrapBootstrap's documentation website (Bootstrap Documentation).
Note |
---|
Prolog Advice: To manipulate strings and atoms in Prolog it is useful to look at the functionalities documentation of the following built-in functions: atomic_list_concat, atom_concat, string_concat, append, maplist, applyTemplate(and maplist here: https://www.swi-prolog.org/. The predicate applyTemplate is a defined predicate that will be explained )below. |
A Quick Prolog
...
Walkthrough
Info |
---|
Tip: for the page ‘start’, the prolog code as already been completed. Use this one as an example on how to implement pages. |
Using Prolog rules in the html.pl
file
You add a condition that checks for a particular pattern id ID to a Prolog rule in the html.pl
file. Other simple conditions that you can add involve counting the number of recipes that are still available while in the recipe selection phase, etc. The general form of the page layout lay-out rules would be something like:
...
There are still many options to vary and for . For example, you can choose the parameters for the myPage
predicate that fit your approach best.
...
Bootstrap is a useful framework for working out a display, but may not be so intuitive in combination with prologProlog. Hereby We provide a short walk-throughwalkthrough 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 bootstrapBootstrap. ‘Card decks’ might be a nice option, so we first look into the code that is involved:
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 is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></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 card has supporting text below as a natural lead-in to additional content.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></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 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 htmlHTML, we see that each of the three images are defined as separate cards. We will now use prolog Prolog to return generate the html HTML for such a card, using a given picture urlURL. The aim is to connect in a single string the static html HTML code and the image url 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-HTML code:
Code Block |
---|
imgCard('<div class="card"><img class="card-img-top" src="~a" alt="Card image cap"></div>'). |
Note that the html HTML is copied, with a replacement of the contents of ‘src’, in the form of ‘~a’ which is a placeholder for the image urlURL. 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 URL of the image, whereas the Html
variable is the output html HTML code for this card. In the body of the rule, the imgCard/1
is queried for to retrieve the html HTML code that we already specified. Then, the Image url URL is placed at the location with `~a' in this html codeHTML 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 HTML we got from bootstrap. We will do this using a self-defined prolog Prolog term, with as input the text, button text and the three images, and as output the html HTML code to render. Within this term, we will start specifying the main template, and then collect the images:
...
Note that atom_concat is used to append the different html-HTML snippets for each of the images. Format is then used to plug in the html 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 URLs can be displayed during the conversation, which you can do using prolog Prolog facts in recipes.pl
.
What is There for You Already
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. |
Displaying
...
Lists
Displaying lists on a screen is a practical feature when dealing with recipe selection and ingredients / utensils per recipe. Hereby some pointers on how to make this possible.
...
The goal here is to render the html HTML code with a list of ingredients / recipes / … as input. We will again break it down, starting with specifying the list items:
...
The way this is defined will look familiar to you, but how are these list items combined together based in a prolog Prolog list? We will add another term for this, ‘myList/2', with as first variable the list of terms, and as second variable the html HTML output:
Code Block |
---|
myList('<ul class="list-group list-group-flush">~a</ul>'). myList(List, Html) :- maplist(myListItem, List, Output), atomic_list_concat(Output, String), myList(T), format(atom(Html), T, [String]). |
Code Block |
---|
myMaplist(_,[],[]). myMaplist(P,[A|As],[B|Bs]) :- call(P,A,B),maplist(P,As,Bs). |
Or an An alternative method is to use the built-in list group item in bootstrap, define each item then add them to a list.
...
Code Block | ||
---|---|---|
| ||
button('<button class="btn btn-light btn-lg m-3" style="font-size:1.5rem">~a</button>'). button(Content, Html) :- button(B), format(atom(Html), B, [Content]). |
Adding a textbox 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. |