I host my own website on a server in my home:
The server software is Apache, which is free software on a GNU licence, and in fact is used on the vast majority of the world's web servers. Since, in my working life (I am retired now) I used to write software, it still amuses me to automate whatever I can, and to write code to accomplish various tasks.
Documented here are:
Uses of JavaScript
Fuzzy Clock
Date Event
Display Last Update
"mailto"
PHP
"Like" Button in Archive
Goon Show Script Search
Recipes
Wordle Tools
LPL and Logic Puzzles
Photo Galleries
JavaScript is a scripting language more or less built in to html. Other scripting languages may be used, but by default if the language is unspecified, anything between "<script>" and "</script>" is assumed to be JavaScript. Extensive debugging tools are available in the Google Chrome browser, and so JavaScript is the automatic choice for adding functionality within a web page. Scripts may be included explicitly on a web page (within a "<script></script>" tag), or included from an external file in the html "<head></head>" tag, for instance:
<head>
<script type="text/javascript" src="dateEvent.js"></script>
</head>
The "Fuzzy Clock" displays at the top of my Home Page. I wanted to have a clock that displayed the time in words rather than numbers, and in addition it should give the time in the same way that a real person might when looking at an analogue clock dial. That is to say, no one would say "The time is two twenty five and twenty seconds", but rather "The time is just gone twenty five past two", and that is the approach I wanted.
The degree of "fuzziness" that I decided on was to have different wording for each minute in any five minutes. Thus, for a time of twenty five past two exactly, it would report "exactly" of course. For a minute before it would say "very nearly", and for two minutes before it would say "coming up to". One minute after would be "just gone", and two minutes "soon after".
There were a few small details to get right, such as reporting if the time is in the morning or afternoon and whether numbers are singular or plural and so on. Once the ".js" file is included in the html page, two things are necessary. Firstly there must be a target for the time. This is done using an id: "<span id='clockTarget'></span>". The clock is kept running using a "tick" function that calls the fuzzyClock function and then calls itself one second later:
<script type="text/javascript" src="fuzzyClock.js"></script>
<body onload="tick()">
<span id="clockTarget" title="This is a Fuzzy Clock."></span>.
</body>
<script>
function tick (){
/ This function will be called once per second
window.setTimeout ("tick()", 1000)
// "clockTarget" is the target ID in the html.
// "true" means that the reported time will start with a capital letter (i.e. "The time is...")
fuzzyClock ( clockTarget, true )
}
</script>
The never-ending series of ticks is started by calling "tick()" as soon as the page is loaded ("<body onload='tick()'>"). The Fuzzy Clock looks like this when it is running:
The "Date Event" displays at the top of my Home Page. At the moment it shows a countdown until the end of Donald Trump's term of office. The idea of the Date Event script is to implement a countdown to a particular time, either a one-off event or one that repeats periodically A number of options are provided, for instance whether to report the count in numbers or words, the timescale for repeating if required, and whether to include the date and time of the target of the count.
A function called "dateEvent" is called with an event name (for instance "Christmas", or "my next birthday"), a date and time for the count, a target ID for where to place the count on the web page, and a number of options. The function is called periodically using a one-second "tick"
<script type="text/javascript" src="dateEvent.js"></script>
<body onload="tick()">
<span id="dateTarget" title="This is a Date Event."></span>.
</body>
<script>
var newYear = new Date(-1,0,1)
function tick (){
// This function will be called once per second
window.setTimeout ("tick()", 1000)
dateEvent ("the next New Year", newYear, dateTarget, 0x21, true )
}
</script>
Note that "the next New Year" starts with a lower case letter. This is because it will be included in a sentence after the reported time remaining.
Note that the options parameter of 0x21 in the example above is in hexadecimal, and represents a binary number of 00100001. This means that words will be used rather than numbers, and that the count should repeat on a yearly basis. The possible options are as follows:
10000000 Add date at the end (e.g. "on 20/01/2029")
01000000 Add time at the end (e.g. "at 12:00:00")
00100000 Use words instead of numbers
00010000 Repeat every minute
00001000 Repeat every hour
00000100 Repeat every day
00000010 Repeat every month
00000001 Repeat every year
Options may be added, although for repeats only the most frequent is used.
The last parameter should be "true" or "false". If set to "true", then the count will be started with "and there", and if false will start with "There". This is so that more than one Date Event may be used in the same sentence.
Here is a Date Event being used as a count-down to New Year:
...and here is another, using words instead of numbers:
This very simple script displays the time and date of the last update to the current web page. It can only be used on static pages, as any attempt to use it on a dynamically generated page will only display the current date and time, i.e. the time that the page was generated.
<body onload="DisplayLastUpdate(lastUpdated)">
<p>Last updated <span id="lastUpdated"></span></p>
</body>
<script>
function DisplayLastUpdate(target){
var modifiedDate = new Date(document.lastModified);
document.getElementById(target).innerHTML = modifiedDate.toDateString()+" "+modifiedDate.toTimeString();
}
</script>
This page was last updated on
"mailto" is a URL (Uniform Resource Identifier) for email addresses. The idea is to have a link on a web page that will open a specified email client so that an email may be sent to the specified adress. It is generally used on a web page so that users can initiate an email back to the author of the web page.
When it works it is very good indeed, and it can be set up so that the email in question has specific headers such as the Subject line.
Unfortunately there are quite a few security issues with the use of "mailto", and also problems in day to day use as quite often it is disabled by a user's current browser.
PHP is a recursive abbreviation meaning "PHP Hypertext Protocol". It is a "server side" language that is relatively simple to learn, but very powerful. It is used to implement client/server computing in a web-based environment. A web server has web pages that a user downloads and "runs" in their own computer. Web pages in a client browser are written in HTML (HyperText Markup Language) and may contain scripts and software written in other languages, such as JavaScript and others. When included in a web page, such additional software is designed to run in your computer. PHP, on the other hand, is designed to run on the server, and return its results to the user as text, usually in HTML form that can then be incorporated into a web page. Thus, an HTML web page may contain very little content itself, but makes a call to a server to get information. The server will run the PHP file, obtain data from, say, a database, assemble its reply in the form of HTML, and "echo" the result back to the calling web page, which may then be displayed however the user's browser wants.
The way that server-side software is accessed is "asynchronous", because when a call is made the client side has no idea when the response might arrive. So, when a call is made, an event "listener" has to be set up to receive the result as and when it appears. This makes the whole client/server relationship more complicated. Parameters may be passed to the PHP software when a call is made.
In the header of every page in my archive, including the main archive menu page, there is a little "Like" button that users may press. This has the effect of playing a sound on the server (so that I can hear it!) and then adds the words "Thank you!" to the web page. It uses PHP in about the simplest form possible. When the button is pressed, a call is made to "Beep.php", which is a very small PHP file on the server:
<?php
// Beep.php
exec("Beep.bat");
echo "Thank you!";
return;
?>
"Beep.bat" is called from the PHP file because PHP itself has no means of playing a sound. It consists of one line:
"C:\{...path to vlc.exe on the server...}\vlc.exe" "{...path to sound files...}\tada.wav"
Try it yourself:
When "Thank you!" is displayed, that means it was successful, and "tada.wav" was played on the server.
Someone sent me a collection of all the scripts for the Goon Show, which I added to the archive on a web page dedicated to them. It occurred to me that it would be a fun thing to be able to search through them for particular words or phrases. Further to that, it would be even more fun to be able to actually play audio clips.
In order to be able to search reasonably efficiently, I put all the scripts into one huge text file, and added markers so that the search could report in which episode the search terms were found. I also allowed for timing information to be added at the start of each line so that audio clips could be played The timing information refers to an offset within the relevant audio file. Links are provided to the individual audio files as well as script files.
The format of each episode within the unified file of all scripts is as follows:
***<Audio filename (without ".mp3")><br/>
<Blank line><br/>
{00:00}<Line One><br/>
{12:34}<Line Two><br/>
{12:35}<...><br/>
<Blank line><br/>
###<Audio filename (without ".mp3")>%%%<br/>
$$$<Script filename (without ".pdf")>£££<br/>
<Blank line><br/>
Timing info takes 7 characters, being minutes and seconds separated by a colon and surrounded by curly brackets at the start of each line of script ("{nn:nn}"). If timing information is not there, a "Play Clip" link will not be displayed.
The script file is searched for the search term. Whenever found, the audio and script filenames are found and links are built. Then, the search term is put into context bracketed by the requested number of lines around it. At the same time, various other stylistic features are added, such as putting the name at the start of each line in bold text and so on. The audio clip is defined using the timing information at the start of each line. I will not discuss any further details of how the search is done here. Suffice it to say that it is reliable and fast, taking only a few seconds in normal circumstances to produce a page with hits in every single episode.
The parameters to the search, which are the number of lines to show for each extract found, the maximum number of results to be returned for each episode, and the search text itself, are echoed in the address bar of the browser. This is so that a search may be repeated by copying what is in the address bar and re-pasting it later. If a search is initiated by pasting into the address bar, then the parameters on the search page are updated to reflect that.
In the Recipes folder, index.html in the browser calls Recipes.php on the server, which in turn returns a list of links to ".txt" files of recipes in a subfolder. Each text file contains a series of optional sections, each one headed by the section name in square brackets Here as an example is the ".txt" file for Creamy Mustard Sauce:
[Title]
Creamy Mustard Sauce (for Asparagus)
[Picture]
Creamy Mustard Sauce.png
Picture produced by AI
[Ingredients]
2 tablespoons mayonnaise
1 tablespoon olive oil
1 tablespoon white-wine vinegar
1 teaspoon Dijon mustard
[Method]
Stir together in a bowl
[End]
When someone clicks on a link to a recipe, a file called Recipes.html is called with the name of the recipe wanted. "Recipes.html" extracts the contents of each section in the ".txt" file on the server using a series of ".php" files, one for each section of the recipe, and displays the results from each call in various places on the html page.
Here is the page for Creamy Mustard Sauce, generated by the text file described above.
The idea of Wordle Tools was to provide a series of tools to help playing Wordle and similar online word games, without providing a full solver but rather just hints. To do this, I wrote a number of programs in BBC BASIC to preprocess lists of words, for instance in alphabetical order, or to prepare lists of four words using different letters, and so on. The tools themselves were written in PHP, and mostly involve searching through various text lists of words to return an answer.
[Include a description of LPL here]
The purpose of the Gallery software is to display folders and subfolders of jpg pictures, together with descriptions. It is mainly intended to display photographic "snaps".
The Gallery system must be on a server that is php enabled. There are ways of finding out if this is the case but they are beyond the scope of this document. Ask your web space provider.
Minimum Installation on the Server
There should be a folder named "Gallery" in the web site root folder, and a subfolder within "Gallery" named "images", which may contain further subfolders of any name to any desired depth.
The Gallery folder must contain the following files:
Gallery.css
Gallery.php
Gallery.ico
Setup.cfg
index.html- The unique index.html for the Gallery system. It is identical in every folder, it makes a call to Gallery.php and displays the result.
"How Gallery Works.txt" - This file
The "images" folder and every subfolder of it must contain:
Gallery.cfg - The file that controls what you see for each folder.
index.html - This file is identical in every folder.
and may also contain:
Picture Files - Any number of picture files (with a ".jpg" extension) that will be displayed automatically provided that Gallery.cfg has been set up correctly. They will be placed alternately on the left and right sides of the screen.
Picture Description files - Optional text files with the same name as picture files but with a ".txt" extension. All lines from such files are displayed below its associated picture, but before the Picture Description text from Gallery.cfg
Gallery.cfg
A configuration text file to be edited by the user, containing the following lines:
Heading - This will be displayed in bold at the top of each page
Subheading- This, along with other lines, is displayed as the top line of a box under the heading.
Backlink - Alternative text for the "back" link. If this line is blank, the heading line from the next level up is used, if found.
Options - A string of binary options, "1" being "true" and anything else being "false", as follows:
- Display Folder Name. If "1", the name of the folder is added to the Heading
- Picture Name. If "1", the filename of each picture is displayed
- Display links as a vertical list if "1", inline separated by dashes otherwise.
- Show Sub-folders. If not "1", then ignore subfolders.
- Show Link Label. If "1", show a brief title at the top of the list of links
- Links in Box. Put a box around both the subheading and associated text, and the list of links.
- Centre Subheading. If "1", centre the subheading on the page.
- Show Backlink. If "1" a link up one level is shown at the top left of the page.
- Show Icon. If "1", an icon "/images/favicon.ico" will be shown as a backlink top left, if present.
- Menu Page. If "1", then this is a page that displays a menu of subfolders.
- Bottom Icon. If "1" then a backlink icon is displayed at the bottom, before the text backlink. This only works if both SHow Icon and Show Backlink are at "1" as well
- Login/Register. If "1" then "Login/Register" appears at the top right of the page.
Notes - Any lines following the optional line "[Notes]" until the start of another opening square bracket ("[") are added to the Subheading text, in a different font from the subheading itself.
Folder Descriptions - If the option is set to display subfolders as a list, then the subheading line from the "Gallery.cfg" file in that folder is displayed after the folder name, and then from the current "Gallery.cfg" any lines following the name of the subfolder in square brackets will be added after the subfolder name on screen as a description.
Picture Descriptions- Any text after the filename of a picture in square brackets up until the start of an opening square bracket ("[") will be added underneath each picture.
A valid example of Gallery.cfg follows:
Pictures of Me
Photographs of me from various sources.
0011011110
[Notes]
All these photos are of me
[Me001.jpg]
[Me004.jpg]
Walking in the New Forest
[Me005.jpg]
A nice cup of coffee.
[]
Notes about the above:
The first two lines are title and subtitle.
No backlink text is supplied here (the blank line). If present, this text is used for the backlink, otherwise the backlink will read the default text "Back to" followed by the title of the folder above.
The line under "[Notes]" will be added to the subtitle box.
"[Me001.jpg]" will have no label.
"[Me004.jpg]" and "[Me005.jpg]" will show the text specified here.
Any picture files not named in Gallery.cfg will be displayed, but without labels.
The file ends with "[]".
The line "0011011110" has 10 options:
1. "0" - The folder name is *not* added to the title.
2. "0" - Filenames of pictures are *not* displayed under each picture.
3. "1" - Links to subfolders are displayed as a vertical list.
4. "1" - Display subfolders. If this option is "0", all subfolders are ignored.
5. "0" - No title for the list of links.
6. "1" - The subtitle and added text, or the list of links are to be displayed in a box.
7. "1" - The subtitle is centred on the page.
8. "1" - A link to the page above the current one appears at the top of the page
9. "1" - An additional icon is added as a backlink, if an icon is present
10. "0" - The current page is not intended to be a menu of links to subfolders
Gallery.php
Gallery.php does quite a lot. It is the main software for Gallery. It accesses a file in each folder called Gallery.cfg, which contains information on how to display the pictures in that folder. The information includes things like heading, subheading, and a series of options controlling how the pictures are to be displayed. If there are subfolders, then it is possible to display a list of those folders. Next to the name of each folder, the subheading from the config file in that folder will be shown. If text for the "backlink" to the next folder up the tree of folders is not specified, the software will extract the heading from the next folder up and use that instead.
Gallery.ico
In the "images" folder or any of its subfolders, an icon may be added having the name "Gallery.ico" that will appear at the top left of a page as an additional backlink to the page above. Note that backlinks to not go higher or further back than the Gallery folder.
Setup.cfg
The "Setup.cfg" file contains any allowable ways of accessing the gallery. "Gallery.php" needs to know these so that it can be removed from the current URL. "Gallery.php" removes any "http://" from the front of the URL, and will also remove any line appearing in "Setup.cfg". Lines in the file might include:
C:/xampp/htdocs/{your root folder}
{your domain}
www.{your domain}
{your IP address}
index.html in "images" folders
Normally a gallery will be accessed with a URL such as "http://{Your domain}/Gallery.index.html" or alternatively "http://{Your domain}/Gallery" and index.html will be started automatically.