JAdVA PHP Library

Jadva_FaqList

Introduction

The Jadva_FaqList part of the JAdVA PHP Library allows you to create simple HTML pages for Frequently Asked Questions. You write down your questions and their answers in a (number of) XML file(s), and the library will convert them to HTML pages. It'll create a page for each group, and a table of contents with all questions. It is also very easy to include images, or to link to other questions.

Getting started

You will need the JAdVA PHP Library. Download it, and unzip it ito a directory. The directory with the library we'll call jadva, make sure the jadva directory contains the bin and library directories from the zip file.

Create another directory for your source XML files, and a third for the outputing HTML files (it's easiest if you keep them all separated). We'll call the directory with the source files src, and the directory with the output files out.

The conversion process

As said, the source for these files are XML files. If you are unfamilair with XML files, w3schools has a section on the eXtensible Markup Language. We've created a Document Type Definition for the XML files. If you are unfamilair with those, w3schools has a section on DTD as well, though you won't have to read through the DTD, as this guide will tell you how your files should look.

A note about encoding: XML files don't have escaping of non-latin characters characters, like HTML does. If you plan on using those, you must make sure to save your file in the encoding you need. We'll be setting the encoding to UTF-8, which is probably good enough for your needs as well.

In the src directory, create a file called 01-main.xml. Jadva_FaqList will read the files in alphabetical order, so naming them 01, 02 etc will guarantee that the groups and questions appear in the order you expect them to. In the this file, the main XML file, put the following text, and save it:

<?xml version="1.0" encoding="UTF-8"?>
<faq name="My first FAQ">
	<home-page>
		This is my FAQ. There are many like it, but this one is mine.
	</home-page>
</faq>

You see that there are no questions in it yet, we'll get to that in a bit.

The faq element contains the whole FAQ as a root element. The home-page element contains the HTML you want on the front page. We now want to generate our HTML files from this (empty) FAQ. To do so, execute the following command:

php jadva/bin/jadva-xml2faq.php  --library jadva/library  --verbose  src/01-main.xml  out

If you are uncomfortable with the command line, open a file called update.bat (or update.sh if you are on a Linux system), and put the text in there. If you are on a Linux system, give the file executable permissions. Then you can simply run this file (either from the command line or from the explorer). If you do use the update script from the explorer, it's handy to ask the script to pause after it's done, that way you can see its output. Add, on a new line, pause (or read if you're on Linux).

Let's explore what this command does:

  1. We call upon the php executable to process our PHP file that converts the FAQ to HTML.
  2. We specify the location of the JAdVA PHP Library, with the --library option, so it can find the included library. This is not required if you use the library as you just downloaded it, but it can help if you want to place the php file into your PATH.
  3. The --verbose option says that we want to know what the application is doing, that way we can debug if anything goes wrong.
  4. We then specify our src/01-main.xml file as input.
  5. And we give our out directory as the directory where the output should go.

Since we enabled the verbose mode, running the script should give you the following output (though with the full directories):

Loading data from src/01-main.xml
1 files added
Saving HTML files to out/
Done.

After running the script, the out directory should contain the following three files:

index.html
This is the main file, containing the home-page HTML code.
style.css
This file contains a basic style script (you can change this later on).
toc.html
This file contains the Table of Contents

If you open the index.html file, you should see your home-page text, and a link to the Table of Contents, which should be empty.

Adding questions

We'll now add some questions to the FAQ. Open the src/01-main.xml file, and change it to look like this:

<?xml version="1.0" encoding="UTF-8"?>
<faq name="My first FAQ">
	<home-page>
		This is my FAQ. There are many like it, but this one is mine.
	</home-page>
	<group name="Math">
		<question text="How much is 2 + 2?">
			2 + 2 = 4
		</question>
		<question text="What is &quot;Squaring a number&quot;?">
			Squaring a number means multiplying it by itself.
		</question>
	</group>
</faq>

We've added the group element and its contents. A group has a name attribute, which is how it'll be shown in the HTML's menu. Each question belongs in one group. We've added two question (element)s. Each question has the text attribute, which is the question itself. Note that in XML, if you use normal quotes, ", in your question, you must escape them to &quot;. Inside the question element is the answer to the question.

Now, if we execute the command to convert the source to the output again, we'll see a new file in the out directory, jadva_faqgrp_100.html. It contains the questions of our Math group, and it's named after its identity. Since we didn't specify an identity for our question group, Jadva_FaqList has generated one for us. Now, if we open index.html, we'll see the Math group added to the menu. Clicking on it shows our questions, including an index, and links back to top. If we click on Table of Contents, we see the questions added there too.

Basically, this is all you need to convert the FAQ XML files to HTML files. There are, however, a number of additional features.

Multiple files

As your FAQ grows, keeping all questions in a single file will become confusing. Luckily, Jadva_FaqList can easily read multiple files if you specify a directory as the input. A good rule of thumb is to put all questions for a single group into a separte file, but there's no requirement on that. Questions in additional files will be added to existing groups if possible. If you want two groups with the same name, you can do so by giving them different ids.

Let's try this out. Create a new file in the src directory, src/02-more.xml, put the following text, and save it:

<?xml version="1.0" encoding="UTF-8"?>
<faq name="My first FAQ">
	<group name="Math">
		<question text="How much is 9 + 9?">
			9 + 9 = 18
		</question>
	</group>
	<group name="Keyboard">
		<question text="What is the shortcut for opening a file?">
			CTRL + o
		</question>
		<question text="What is the shortcut for saving a file?">
			CTRL + s
		</question>
		<question text="What is the shortcut for creating a new file?">
			CTRL + n
		</question>
	</group>
</faq>

The quesions in this file are for the same FAQ, My first FAQ. There is one question for the existing group Math, and three questions for the new group Keyboard. Please keep in mind that questions will be added in order, though the table of contents sorts them alfabetically.

Now we must change our command to include this file as well. To make use of multiple input files, we specify a directory as the input. All files in that directory with the xml extension are then assumed to be FAQ files. The new conversion command is:

php jadva/bin/jadva-xml2faq.php  --library jadva/library  --verbose  src  out

Note that we've only changed the input from src/01-main.xml to src. Running the script should now give the following output, (again, your output should show the full directories):

Loading data from src/01-main.xml
Loading data from src/02-more.xml
2 files added
Saving HTML files to out/
Done.

Afterwards, a fifth file should appear in your out directory, called jadva_faqgrp_101.html. Opening the index.html should now have the Keyboard group in the menu, and the questions should be added to the Math group.

Normal file names

The HTML files for the groups are called after the identity, but since we have specified no identity, an unique identity is generated. This results in files with rather unusable names. You can easily fix that, by adding an id tag to each group. Change the files as follows:

src/01-main.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faq name="My first FAQ">
	<home-page>
		This is my FAQ. There are many like it, but this one is mine.
	</home-page>
	<group id="faq.math" name="Math">
		<question text="How much is 2 + 2?">
			2 + 2 = 4
		</question>
		<question text="What is &quot;Squaring a number&quot;?">
			Squaring a number means multiplying it by itself.
		</question>
	</group>
</faq>

src/02-more.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faq name="My first FAQ">
	<group id="faq.math">
		<question text="How much is 9 + 9?">
			9 + 9 = 18
		</question>
	</group>
	<group id="faq.keyboard" name="Keyboard">
		<question text="What is the shortcut for opening a file?">
			CTRL + o
		</question>
		<question text="What is the shortcut for saving a file?">
			CTRL + s
		</question>
		<question text="What is the shortcut for creating a new file?">
			CTRL + n
		</question>
	</group>
</faq>

Note that we've added a id attribute to the Math group in the first file and the Keyboard group in the second file. We've also removed the name attribute from the Math group in the second file, and replaced it by the id attribute, since ids are checked before names, and we don't need to add the name attribute again.

If you run the update command again, you'll see two new files in the out directory, faq.math.html and faq.keyboard.html. (You can safely remove the old files, jadva_faqgrp_100.html and jadva_faqgrp_101.html. In fact, you can safely remove all files from the out directory, since you can simply recreate them by running the update command).

Linking to other questions

Sometimes two or more questions are closely related. Then it'd be handy if you could simply move from one of those questions to the others. For that, we have added the qlink tag. It works similar to HTML's a tag, only instead of giving it a full url, you give it the id of a question. Let's try this out. Change src/02-more.xml to be as follows:

<?xml version="1.0" encoding="UTF-8"?>
<faq name="My first FAQ">
	<group id="faq.math">
		<question id="faq.math.addTwoNines" text="How much is 9 + 9?">
			9 + 9 = 18
		</question>
	</group>
	<group id="faq.keyboard" name="Keyboard">
		<question text="What is the shortcut for opening a file?">
			CTRL + o
		</question>
		<question text="What is the shortcut for saving a file?">
			CTRL + s
		</question>
		<question text="What is the shortcut for creating a new file?">
			CTRL + n
		</question>
		<question text="How do I add two numbers?">
			This is not a keyboard questions. See <qlink href="faq.math.addTwoNines">this question</qlink>.
		</question>
	</group>
</faq>

Note that we've added an id attribute to the math question, and that we've added a question to the Keyboard group. Note that the id is unique over all questions in the faq, not just the questions in its group or in its file, so you need to be carefull with what id you give it.

After running the update command, you should see the new question in the Keyboard group. Clicking on the link should then take you to the right question in the Math group.

Adding images

Sometimes you want to include an image, and we'll show you how that's done. Find an image to include (we'll use Mark James's famfamfam map icon), and put it in the src directory. Then, change src/02-more.xml to be as follows:

<?xml version="1.0" encoding="UTF-8"?>
<faq name="My first FAQ">
	<group id="faq.math">
		<question id="faq.math.addTwoNines" text="How much is 9 + 9?">
			9 + 9 = 18
		</question>
	</group>
	<group id="faq.keyboard" name="Keyboard">
		<question text="What is the shortcut for opening a file?">
			CTRL + o
		</question>
		<question text="What is the shortcut for saving a file?">
			CTRL + s
		</question>
		<question text="What is the shortcut for creating a new file?">
			CTRL + n
		</question>
		<question text="How do I add two numbers?">
			This is not a keyboard questions. See <qlink href="faq.math.addTwoNines">this question</qlink>.
		</question>
	</group>
	<group id="faq.icons" name="Icons">
		<question text="What is the icon for a map?">
			<img src="map.png" />
		</question>
	</group>
</faq>

Note that we've added a question with a simple img element as answer. The src is read by Jadva_FaqList, and is relative to the src directory. You can add subdirectories, the structure will be mimicked in the out directory. So if you'd create an img directory in the src directory, and move the map.png file there, the src should be img/map.png.

Style

The (basic) style may not be to our liking. We'll show you how to use a stylesheet of your own. First, create a new file in the src directory called myStyle.css, put the following content in it, and save it:

ul.group_menu {
	width: 15%;
	float: left;
}

#main_content {
	width: 60%;
	float: left;
}

Now change the command to also use the new style (the stylesheet is expected to be in the src directory, so the path should be relative from there):

php jadva/bin/jadva-xml2faq.php  --library jadva/library  --style myStyle.css --verbose  src  out

After running the update command again, your style should be used. You can verify that by looking at the menu; the color should be your default link color, instead of black, and the spacing after the Home link and before the Table of contents link should be gone. Note that the file you specify is copied to the out directory and renamed to style.css.

You can now use this CSS file to change the look and feel of the generated FAQ. If you are unfamilair with CSS, w3schools has a section on these Cascading Style Sheets.

More extensive customization is not yet possible via the script, however, if you have some skill in PHP, you can extend the Jadva_FaqList class yourself, and override the _generateIndex, _generateFaqPage and _generateToc function to generate the output you want.

Other HTML

Other HTML tags in your answers will by copied one on one. For example, if you change the src/01-main.xml file to look like this (notice the em tag added around multiplying):

<?xml version="1.0" encoding="UTF-8"?>
<faq name="My first FAQ">
	<home-page>
		This is my FAQ. There are many like it, but this one is mine.
	</home-page>
	<group id="faq.math" name="Math">
		<question text="How much is 2 + 2?">
			2 + 2 = 4
		</question>
		<question text="What is &quot;Squaring a number&quot;?">
			Squaring a number means <em>multiplying</em> it by itself.
		</question>
	</group>
</faq>

After running the update command, multiplying should now be emphasised (usually rendered in italic font).

Trouble shooting

When something goes wrong with the conversion, it might be usefull to validate the XML. There are various XML valdation services online (xmlvalidation.com, w3c Markup Validation Service, etc) and offline (XML Copy Editor, etc). There's a little catch in our system: the content of our question elements can be various things.

Plain text answers

The simplest version is plain text. Example:

<question text="What is the multiplication tabel of 4?">
	0 x 4 = 0
	1 x 4 = 4
	2 x 4 = 8
	...
</question>

If you use only text, and no tags at all, the content is assumed to plain text, and newlines are copied as newlines to the output.

HTML code

You can just use HTML code in your answers. Example:

<question text="What is &quot;Squaring a number&quot;?">
	Squaring a number means <em>multiplying</em> it by itself.
</question>

This'll work 99% of the time. However, it is not valid XML according to our DTD, so you cannot validate it. Also note that you have to add breaks yourself:

<question text="What is &quot;Squaring a number&quot;?">
	Squaring a number means <em>multiplying</em> it by itself.<br />
	The idea is similar to a square,
	which is a rectangle with all sides equally long.
</question>

Proper HTML code

The proper way to use HTML is to esacpe the text. The HTML is then not really part of the XML itself, but rather of the answers. The easiest way to do that, is by encapsulating your answer between <![CDATA[ and ]]>. Example:

<question text="What is &quot;Squaring a number&quot;?">
	<![CDATA[Squaring a number means <em>multiplying</em> it by itself.]]>
</question>

DTD

You can find the Document Type Definition at standards.jadva.net. You'd include it as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faq SYSTEM "http://standards.jadva.net/faq-list/faq-list-0.2.dtd">
<faq name="My first FAQ">
	...
</faq>

Conclusion

This concludes this tutorial on generating HTML FAQs using XML files and Jadva_FaqList. I hope you find it easy to use.