Return to Snippet

Revision: 77505
at September 27, 2019 11:49 by daemondevin


Initial Code
<?php
/**
 * gaetDoctype
 *
 * Copyright 2016 by demon.devin <[email protected]>
 * Created on 10-07-2016
 *
 * getDoctype is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * getDoctype is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * getDoctype; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * @package getdoctype
 */
/**
 * getDoctype
 *
 * @author     daemon.devin
 * @link       PortableAppz.x10.mx/
 * @copyright  2016
 * @package    getDoctype
 * @version    1.0
 * 
 * With this snippet you will have the ability to display the DOCTYPE while sending the
 * correct headers with support for content type negotiation.
 * 
 * It also will correct itself for the W3C validator which does not send the correct Accept
 * header for XHTML documents.
 * 
 * Does NOT send XHTML 1.1 to browsers that wont accept application/xhtml+xml because the
 * snippet will make sure the browser groks XML before sending anything.
 * visit: labs/PHP/DOCTYPE.php#bug-fix for details and a link to the W3C XHTML for more
 * 
 * 
 * PROPERTIES
 * $doc       string   required    Defaults: XHTML
 * Either HTML or XHTML 
 * 
 * $type      string   optional    Defaults:  Strict
 * One of three chooses between Strict, Transitional, or Frameset
 * 
 * $ver       string   optional    Defaults: 1.1
 * For XHTML: 1.0 or 1.1 | For HTML5: 5
 * 
 * $charset   string   optional    
 * 
 * $lang      string   optional    
 * 
 * $s         string   optional    Defaults: ' '
 * Specify prefered indentation. Either '\t' (tab) or ' ' (whitespace) or any combination 
 *
 * USAGE
 * require_once('getDoctype.inc.php');
 *
 * EXAMPLE 
 * To specify html5 use the following:
 * $doc='html' 
 * $ver='5'
 *
 * Output: 
 * <!DOCTYPE html>
 * <html lang="en">
 *  <head>
 *   <meta charset="UTF-8">
 *
 * To specify XHTML using Strict with version 1.1 use the following:
 * $doc='xhtml' 
 * $type='strict' 
 * $ver='1.1'
 *
 * NOTE: This sends the XML declaration before the DOCTYPE
 *       but this will put IE into quirks mode which we don't 
 *       want so it omits it for IE
 * 
 * Output: 
 * <?xml version="1.0" encoding="utf-8"?>
 * <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
 *  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 * <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 *
 */

$doc     = ''; // html or xhtml
$type    = ''; // choose between strict, transitional, or frameset
$ver     = ''; // XHTML: 1.0 or 1.1 | HTML: 4.01 or 5
$charset = ''; // Charset (i.e. UTF-8)
$lang    = ''; // Language (i.e. en)
$s       = ''; // Indentation. Either '\t' (tab) or ' ' (whitespace) or any combination.

$output = '';

$media = array('HTML' => 'text/html', 'XHTML' => 'application/xhtml+xml');

$doc = strtoupper($doc);
$type = strtolower($type);

$avail = 'PUBLIC'; // or SYSTEM, but we're not going there yet

// begin FPI
$ISO = '-'; // W3C is not ISO registered [or IETF for that matter]
$OID = 'W3C'; // unique owner ID
$PTC = 'DTD'; // the public text class

$PTD = '';
$PCL = 'EN'; // as far as I know the PCL is always English
$URI = 'http://www.w3.org/TR/'; // DTDs are all under the Technical Reports (TR) branch @ W3C

$doc_top = '<html'; // what comes after the DOCTYPE of course
$meta = '<meta ';

if($doc == 'HTML') {

	if($ver == '5') {

		$top = 'html';
		$media_type = $media['HTML'];
		$meta .= 'charset="'.strtoupper($charset).'" />';

	}
	else {

		$top = $doc;
		$media_type = $media[$doc];

		$PTD = $doc.' 4.01'; // we're only supporting HTML 4.01 here

		switch ($type) {

			case 'frameset':

				$PTD .= ' '.ucfirst($type);
				$URI .= 'html4/frameset.dtd';
				break;

			case 'transitional':

				$PTD .= ' '.ucfirst($type);
				$URI .= 'html4/loose.dtd';
				break;

			case 'strict':
			default:

				$URI .= 'html4/strict.dtd';
		}
		$meta .= "http-equiv=\"Content-Type\" content=\"$media_type; charset=".strtoupper($charset)."\">";
	}
	$doc_top .= ' lang="'.$lang.'">';


}
else {

	// must be xhtml then, but catch typos

	//if($doc != 'XHTML')
	$doc = 'XHTML';

	$top = 'html'; // remember XML is lowercase
	$doc_top .= ' xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$lang.'"';

	// return the correct media type header for this document,
	// but we should probably make sure the browser groks XML!

	// the W3C validator does not send the correct Accept header for this family of documents, sigh
	if(stristr($_SERVER['HTTP_USER_AGENT'], 'W3C_Validator')) $media_type = $media['XHTML'];
	else  $media_type = (stristr($_SERVER['HTTP_ACCEPT'], $media['XHTML']))?$media['XHTML']:$media['HTML'];

	// do NOT send XHTML 1.1 to browsers that don't accept application/xhtml+xml
	// see: labs/PHP/DOCTYPE.php#bug-fix for details and a link to the W3C XHTML
	// NOTES on this topic

	if($media_type == $media['HTML'] and $ver == '1.1') $ver = '1.0';

	if($ver == '1.1') {
		$PTD = implode(' ', array($doc, $ver));
		$URI .= 'xhtml11/DTD/xhtml11.dtd';
	}
	else {
		$PTD = implode(' ', array(
			$doc,
			'1.0',
			ucfirst($type)));
		$URI .= 'xhtml1/DTD/xhtml1-'.$type.'.dtd';

		// for backwards compatibilty

		$doc_top .= ' lang="'.$lang.'"';
	}

	$doc_top .= '>'; // close root XHTML tag

	// send HTTP header
	header('Content-type: '.$media_type.'; charset='.$charset);

	// send the XML declaration before the DOCTYPE, but this
	// will put IE into quirks mode which we don't want
	if(isset($_SERVER['HTTP_USER_AGENT']) && ((strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') == false) || strpos($_SERVER['HTTP_USER_AGENT'],
		'Trident') == false)) {
		$output .= '<?xml version="1.0" encoding="'.$charset.'"?>'.PHP_EOL;
	}

	$meta .= "http-equiv=\"Content-Type\" content=\"$media_type; charset=".strtoupper($charset)."\" />";

}

$FPI = implode('//', array(
	$ISO,
	$OID,
	$PTC.' '.$PTD,
	$PCL));

if($doc == 'HTML' && $ver == '5') {
	$output .= '<!DOCTYPE '.$top.'>'.PHP_EOL;
	$output .= $doc_top.PHP_EOL;
	$output .= "$s<head>".PHP_EOL;
	$output .= "$s$s$meta".PHP_EOL;
}
else {
	$output .= "<!DOCTYPE $top $avail \"$FPI\" ".PHP_EOL."$s\"$URI\">".PHP_EOL."$doc_top".PHP_EOL."$s<head>".PHP_EOL."$s$s".
		$meta.PHP_EOL;
}
return $output;

Initial URL
http://portableappz.x10.mx/extras/getDoctype

Initial Description
With this snippet you will have the ability to display the `<DOCTYPE>` while sending the correct headers with support for content type negotiation.

It also will correct itself for the W3C validator which does not send the correct Accept header for `XHTML` documents.

Does **NOT** send `XHTML 1.1` to browsers that wont accept `application/xhtml+xml` because the snippet will make sure the browser groks XML before sending anything.
Visit: labs/PHP/DOCTYPE.php#bug-fix for details and a link to the W3C XHTML for more

Initial Title
getDoctype.inc.php

Initial Tags
html, xhtml, xml

Initial Language
PHP