I'll explain how to make a web page which displays unique combinations of fragments of content, which means that
similarly to Queneau's ten million poems, the page will assemble different combinations each time it is visited.
Incidentally, this page itself is a static web page. No scripts here, only descriptions of how to write them.
Most of the web pages on this domain are static and use no scripting whatsoever. The only exception are the few pages that
display mathematical formulae. Since I have had little interest in dynamic web pages, until quite recently, I had not bothered
looking into JavaScript or any other languages for web scripting. But, in the spirit of my generative text program
Peptalk, I started experimenting with a web page that
would load random selections of text and images and create unique combinations every time it is loaded.
Having some background in C programming, the basics of JavaScript turned out to be surprisingly easy.
The intricacies are in getting it to interact correctly with html and css.
In my very dynamic web page, almost every element is chosen randomly from a list and loaded by script. The trick for
generating random integers and selecting items from a list is described in many tutorials and beginners' guides, but I'll
include it here for completeness. Say you have a separate JavaScript file. In it, near the top, goes the following
function declaration which will be called many times throughout the script.
function rnd(n)
{
var xi = Math.floor(Math.random() * n) ;
return xi;
}
This function returns random integers in the range 0 to n–1. In the html document, an element with an id tag can be replaced
by a random element. Suppose we have a text paragraph, something like this:
<p id="will_be_replaced"> this text will be modified </p>
In the script file we define a function, let's call it replace()
.
function replace()
{
var newtext = ["one phrase", "other phrase"] ;
var x = rnd(newtext.length) ;
document.getElementById('will_be_replaced').innerHTML = newtext[x] ;
}
The innerHTML works with text replacements, but if instead you wish to point a link to a random web page it looks slightly
different. This example changes the text of the link as well as the address it points to. First, the relevant line in
the html document:
<a href="javascript:websurf()" id="link_name">link text to be replaced</a>
In the script file, we define a websurf function which takes you to an undisclosed random location. Such link roulettes
are perhaps not considered good practice since the destination is obscured and you will have to trust the website owner that
they do not lead to anything nefarious.
function websurf()
{
var address = ["https://example.com", "example.net", "http://weirdo.info"] ;
var x = rnd(address.length) ;
window.location = address[x] ;
}
The function to replace the link text is similar to the replace()
function that modifies text inside of a paragraph,
except in its last line.
function change_text()
{
var linktext = ["silly link", "somewhere", "not here"] ;
var x = rnd(linktext.length) ;
document.getElementById('link_name').text = linktext[x] ;
}
In other words, instead of .innerHTML we use .text to access the element to be replaced.
Inserting text files and images
The first component I looked into was a text box which is filled with content from one of several plain
text files written in various languages. For this I used the html <object>
element to insert the plain text file.
<object id="postbox" type="text/plain;charset=UTF-8" data="" width="500" height="300">
Default text goes here (if content can't be displayed).
</object>
The empty data field will be filled with text from one of the input files.
As I experimented with this at home, I had specified the parameter of type only as "text/plain", and everything
worked fine. However, after I uploaded the files it turned out that the non-ascii letters of non-english languages
turned into garbage, and it took some time to troubleshoot this. Obviously the character set should be utf-8,
but that was already declared in the html head section. After trying various
places to specify the character set of this object and after days of web searches, I finally found what ought to be
the correct solution. It's just that it doesn't work on Firefox, although it does work on some other browsers.
The function that inserts a file into the object box is structurally similar to the other text replacement functions.
Assuming that the text files are put into a directory called "textcatalog" it might look as follows:
function textbox()
{
var textfiles = ["file1.txt", "file2.txt"] ; // actually many more files
const tbox = document.getElementById('postbox');
var x = rnd(textfiles.length) ;
tbox.data = "textcatalog/" + textfiles[x] ; // string concatenation
}
For insertions of images into the web page I used the function document.write()
, which simply injects html code
at the specified point where it's called in the html document. The idea is simple enough, but it took me a few attempts to
figure out that some escape sequences were necessary. Here all image files are placed in a directory named "pic" and the
variable insertcode holds the html code that loads the chosen image. The + sign does string concatenation and
the backslash is used for escape characters.
function insert_image()
{
var im = ["img1.jpg", "img2.jpg"] ; // long list of small pictures
var x = rnd(im.length);
var insertcode = "<img src=\"pic/" + im[a] + "\" alt=\"arbitrary\" width=\"250\" height=\"250\"> " ;
document.write(insertcode) ;
}
In the html document, this is called at the appropriate location by <script>insert_image();</script>
.
Finally, all the elements have to be loaded into the document at some point, as the cause of some action. Perhaps
the cleanest way to do so is to load everything at once as the page itself loads. In the <head>
section
I include the JavaScript file, and then in the body section everything is loaded with <body onload="inject()">
where the function inject()
collects and calls all the other functions. Hence it should be put at
the bottom of the JavaScript file.
function inject()
{
replace();
websurf();
change_text();
textbox();
// etc.
}
For even more variability, style elements such as the page colour and layout could be dynamically altered,
but that's an experiment for another day. To see everything in action, visit
the marvelous web page!