...
Using and Understanding the code in html.pl
We illustrate how the predicates introduced above can be used to create more complex HTML code with a card deck example. We also briefly discuss how the Prolog clauses for these predicates have been defined.
A Quick guide to using Bootstrap components not defined in html.pl
...
For the card-body class we can use the div/4
predicate, where we use the CardBodyContent
variable to replace the default input argument Content
variable for this predicate and fill in the class and style arguments. We name the output argument CardBodyElement
and then we get as our next piece of code the following:
Code Block |
---|
div(CardBodyContent, 'card-body', '', CardBodyElement) |
For creating the card, we also need an image (again we do not bother to fill in the … ...
in the example, which we leave up to you; check out the
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
https://socialrobotics.atlassian.net/wiki/spaces/PM2/pages/2264236033/Visual+Support+Guide#img-tag section above on how to do that). We use the img(+Source, +Class, +Style, -Html)
predefined predicate and use CardImage
as output variable:
Code Block |
---|
img('...', 'card-img-top', '', CardImage) |
Now we have code to generate the two elements that we need to create a card
class element, we can piece these two elements together using the div/4
predicate to generate code for that element. Phrases like piece these together by now should have alerted you to the fact that atomic_list_concat
might be useful! We write the following Prolog code to generate the card
element:
Code Block |
---|
atomic_list_concat([CardImage, CardBodyElement], CardContent),
% We need three cards!
atomic_list_concat([CardContent, CardContent, CardContent], CardContent3Times),
div(CardContent3Times, 'card', '', CardDeckContent) |
Finally, as a last step, we now can create our card-deck using div/4
again as follows:
Code Block |
---|
div(CardDeckContent, 'card-deck', '', Html) |
We now have all the different Prolog queries that we need, in the right order, to create one big query that will generate the complete HTML code for the card deck. We simply need to add commas in between these queries (used as conjuncts) to obtain our complete Prolog query:
Code Block |
---|
% Prolog query that generates HTML code for a three-card card deck
% First, we generate the content for the card body
atomic_list_concat([
'<h5 class="card-title">Card title</h5>',
'<p class="card-text">This is the third card.</p>'], CardBodyContent),
% then we generate the card body element
div(CardBodyContent, 'card-body', '', CardBodyElement),
% then we generate the card image element
img('...', 'card-img-top', '', CardImage),
% and then we generate the content for the card deck
atomic_list_concat([CardImage, CardBodyElement], CardContent),
% We need three cards!
atomic_list_concat([CardContent, CardContent, CardContent], CardContent3Times),
div(CardContent3Times, 'card', '', CardDeckContent),
% so we can finally create the card deck html element
div(CardDeckContent, 'card-deck', '', Html).
% The Html output variable will return the complete card deck HTML code we showed above. |
The HTML code and query above, of course, will not work yet as we used three dots ...
for the src
attribute. You will still need to make sure that the right image URLs (or Base64 codes) are used to replace these dots and modify the accompanying text in the card bodies to match with these images.
Defining new predicates for generating HTML elements
...