You are here: start » code_conventions

Code Conventions


FIXME rewrite complete article

FIXME link to

Hard to believe, but there are a couple of plugins and templates with tags written in upper case like “<BR>”.

This won't validate under XHTML; its really out and uncommon. Years ago it was common for making the source-code better readable. Today it's common to use a modern editor with syntax-higlighting for all the popular markup- and programming-languages

So please replace all the tags written in uppercase by tags in lowercase in your templates and other PHP files.

Doctype Declaration

The first step to create a template is to declare a Doctype Definition (DTD) dynamically via PHP depending on the settings of “xhtml_endtags”:

<?php if ($cf['xhtml']['endtags'] == 'true'):?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
<html xmlns="" <?php echo strlen($sl) == 2 ? 'lang="' . $sl . '" xml:lang="' . $sl . '"' : '';?>>
<?php else:?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
<html <?php echo strlen($sl) == 2 ? 'lang="' . $sl . '"' : '';?>>
<?php endif;?>
Simply use the HTML5 doctype for new templates:
<!DOCTYPE html>
<html <?php echo strlen($sl) == 2 ? 'lang="' . $sl . '"' : '';?>>

If you don't care about CMSimple_XH 1.5.x subsites, you can even simplify further:

<!DOCTYPE html>
<html lang="<?php echo $sl;?>">

Followed by:

<head> ...

The opening <html> tag is included in the PHP conditional, because it has the xmlns and xml:lang attributes only for XHTML. The lang resp. xml:lang attribute is set on the HTML element dynamically. For subsites, where the actual language is not known, these attributes are omitted.

The function tag()

This CMSimple_XH function allows to use all empty elements such as <hr> and others to be printed out with or without the trailing backslash depending on the setting of “xhtml_endtags”.

We do know that XHTML is not just “HTML with required end-tags”, but emitting of empty elements with or without the trailing backslash is the minimum requirement for making templates and plugins optionally conforming to either markup language.

tag() is a CMSimple_XH built-in function and can be used as follows:

<?php echo tag('br');?>
causes: <br> or <br />
<?php echo tag('hr');?>
causes: <hr> or <hr />
<?php echo tag('img src="..." alt="..."');?>
causes:  <img src="..." alt="...">
or:      <img src="..." alt="..." />

… depending on the setting of “xhtml_endtags”

Be careful with more complex tags like <img…> especially if PHP variables are used within the tag. But you'll become attuned with it soon.

Often a “&” in dynamic created links is the cause of validation-errors. “Special” characters in the (X)HTML output have to be masked as entity references:


(depending on the markup language and the context the rules are relaxed)

That was the reason, why the printlink of CMSimple didn't validate. It could be solved by replacing the ”&“ via the PHP function htmlspecialchars().

Here for example a the relevant part of printlink() out of cms.php:

    elseif (sv('QUERY_STRING') != '') $t = htmlspecialchars(sv('QUERY_STRING'), ENT_COMPAT, "UTF-8") . $t;
    return '<a href="' . $sn . '?' . $t . '">' . $tx['menu']['print'] . '</a>';

In the first line of code, the variable $t is created out of the QUERY_STRING, which may contain one or more ”&“ characters.

In the second line, the variable $t is used to create a link. Without handling the QUERY_STRING with htmlspecialchars(), the ”&“ will be printed out unmasked, which would result in invalid (X)HTML.

BTW: the use of htmlspecialchars() before writing user input to the (X)HTML output will not only avoid validation errors, but also security issues such as XSS attacks.

Scripts and CDATA

In some templates and/or plugins you'll find javascript sections. You have to take care that these sections won't get treated as #PCDATA (parsed character data) by an XHTML parser, as this would give ”<“ and ”&“ a special meaning.

The solution is to declare the scripts as #CDATA (character data):

<script type="text/javascript"> 
/* <![CDATA[ */ 
// javascript code goes here
/* ]]> */ 

The #CDATA declaration has to be commented out, as otherwise it would be treated as part of the script, what would result in syntactically invalid javascript.

Please note that the #CDATA declaration is not necessary for HTML, but it doesn't hurt either.

FIXME Add info about necessary escaping for HTML (i.e. SGML) parsers.

2 versions

If you have an XHTML-valid plugin or template it's often a piece of cake, to convert it into an HTML-valid one. (Remeber: an XHTML-only template- or plugin-package may be named like:

Just do a “search & replace” for ” />“ into ”>“ in all PHP-files and you got your HTML-version of the XHTML-template/-plugin. But be careful and check the new HTML version, as HTML isn't simply XHTML without the empty element shorthand.

Then you can rename the XHTML-version, which is marked with a uppercase “X” at the end into a HTML-version with a uppercase “H” at the end.

Dont't forget: within a template, the DTD (Doctype) has to be changed accordingly.

The future with HTML5

Basically all HTML 4.01 strict and XHTML 1.0 strict conforming documents are conforming to HTML5 too. HTML5 allows using tags with and without the trailing backslash.

But some HTML attributes that are allowed in the transitional variants of HTML 4.01 and XHTML 1.0 like “border” are invalid in HTML5. This is a consequent step into a strict separation from content and design. There is no transitional-version in HTML5.

We recommend to develop templates and plugins in HTML 4.01 and/or XHTML 1.0 using the strict-version, if you don't need any features of the transitional variants that are conforming to HTML5 (e.g. IFrames). It might be best to deliver templates in the transitional variants, to avoid problems with plugins that make use of such features.

If so, you won't have big trouble to convert to HTML5 later. Just use the genious simple doctype of HTML5:

<!DOCTYPE html>

that's it.

It will last some years until HTML5 will be official released, until all browsers will support HTML5 and it's features and especially the editors will generate output that makes use of the improved features of HTML5 for semantic markup.

But our effort on writing correct (X)HTML isn't for nothing. Even the name CMSimple_XH will last because HTML5 is a joining of HTML 4.01 strict and XHTML 1.0 strict. FIXME nonsense

The user will be able to create content with or without trailing-backslashes in empty elements, but in HTML5 this will no longer play a part in validation.

Using the trailing-backslash is required for XML conformance, and some users might prefer using XHTML5.

You are here: start » code_conventions
Except where otherwise noted, content on this wiki is licensed under the following license: GNU Free Documentation License 1.3
Valid XHTML 1.0 Valid CSS Driven by DokuWiki