---++ Rule definition facilities (html//1 rules) In addition to the [[core translation][]] of Prolog terms to HTML, the library(http/html_write) defines an escape mechanism that allows you to write rules. In this page, we present a web-server that lists all Prolog modules and the file from which they are loaded. We start with the overall server and the skeleton of the page using the code below. But, instead of filling out all the details in one giant structure, we call rules (or macros) using the \ construct. The advantage of this approach is that the structure of the page remains obvious. In addition, the page-skeleton becomes _reusable_ by providing different parameters to the rules. == :- use_module(library(http/thread_httpd)). :- use_module(library(http/http_dispatch)). :- use_module(library(http/html_write)). :- http_handler(root(list_modules), list_modules, []). server(Port) :- http_server(http_dispatch, [port(Port)]). list_modules(_Request) :- findall(M, current_module(M), List), sort(List, Modules), reply_html_page(title('Loaded Prolog modules'), [ h1('Loaded Prolog modules'), table([ \header % rule-invocation | \modules(Modules) % rule-invocation ]) ]). == Now, we complete the definition of the skeleton by providing definitions for the called rules. These definitions are [[DCGs][http://cs.union.edu/~striegnk/learn-prolog-now/html/node54.html#lecture7]] (Definite Clause Grammar rules). The _input_ arguments of the DCG rules are parameters and the _output_ list is a list of HTML tokens created by means of calling html//1. The argument of html//1 must obey the same rules as the arguments of reply_html_page/2. == header --> html(tr([th('Module'), th('File')])). modules([]) --> []. modules([H|T]) --> module(H), modules(T). module(Module) --> { module_property(Module, file(Path)) }, !, html(tr([td(Module), td(Path)])). module(Module) --> html(tr([td(Module), td(-)])). == We managed to compensate for the disadvantages compared to writing HTML/XML: we have _reusable_ skeletons and components: we can reuse skeletons as in the top-box by passing arguments that fill the table header and body and we can reuse components as defined in the bottom-box in different tables. _Reusability_ may not be a big issue for pages that consists mainly of text, but dynamically generated pages often contain lots of reusable elements! The rule below shows one for formatting integers in a cell as N,NNN,NNN... This example illustrate another type of value that can appear in the html//1 content: terms of the form -, where _format_ is an atom and _arguments_ is a list of arguments that is passed to format/2. == ... html(tr([..., \int_cell(I), ...])), int_cell(I) --> html(td(class(intcell), '~D'-[I])). == In the next example, we extend our program by making more use of rules and dealing with HTTP-_parameters_ (i.e., ?name=value&...) @see The source: list_modules.pl @see Next: [[Processing HTTP-parameters][]]