Hi all, I'd like to put forward the proposal that we switch to HTML5 for all Django supplied templates in Django 1.4 (apart from some of the GIS templates which apparently require XHTML to work under IE). I'm quite prepared for this to get shot down in flames, but I think it is at the point where it is worth suggesting.
For reference, Rails switched their to outputting HTML5 by default with Rails 3, released last August (and obviously this was in trunk for some months before). The change would require changing doctypes only, and not any of the other HTML we render. This is because XHTML style tags are valid HTML5. All the other complications of a switch from XHTML -> HTML are mitigated (completely mitigated, as far as I can tell) by the fact that we serve as 'text/html' by default, which means that our generated pages have always been treated as HTML rather than XHTML anyway. (I suspect that extremely few are serving as application/xhtml+xml, if any. You will probably find that the admin has various bugs if you try to serve it is application/xhhtml+xml) Because of this tolerance in the HTML5 spec, this is quite different from switching to HTML4 (or supporting HTML4), which I was against [1]. I would suggest we carry on generating XHTML-style code indefinitely for backwards compatibility with pages that have XHTML doctypes. Going forward we can start to use HTML5 features at least as an option in places like the admin. So the patch is very small and simple (attached). It remains to be seen whether the change will be as simple in practice as in theory. If we put it in early in the release cycle we can get some testing and see if there are subtle problems. == Advantages == 1) It will allow us to use HTML5 in the admin and other places, where it is has browser support or is sufficiently backwards compatible (e.g. <input type="email"> and <input type="text" pattern="..."> could be used today with no issues as far as I am aware). 2) It will allow other people to use more advanced features of HTML5 as they see fit. (Although you can argue that they can do so without an HTML5 doctype, but they can't have document validity). 3) We avoid fragmenting the re-usable apps ecosystem into the different dialects of HTML by encouraging everyone to move to HTML5. This is a significant issue, and we are at the point where it is becoming important, as more and more people will be wanting to use HTML5 features. 4) We will have a 'solution' for all the HTML4 related tickets: http://code.djangoproject.com/ticket/6925 http://code.djangoproject.com/ticket/7281 http://code.djangoproject.com/ticket/7452 (Admittedly it is not a solution, because we will still not be providing HTML4 support. But we will have an answer for people who object to XHTML doctypes for whatever reason). 5) This is the 'right' thing - serving XHTML as text/html was never really the best thing. It even causes failure with some validators like validator.nu which compare the http-equiv Content-Type with the expected Content-Type (from HTTP or doctype). 6) It could simplify things like Russell's proposed form rendering [2] - one less variable and code path is definitely a plus. == Problems == 1) HTML5 is not finished. But apparently it may be difficult to ever say that it is finished. [3] And if we stick to the parts that are stable and well supported by browsers in terms of what we actually ship with Django, this is not an issue. 2) Lack of offline HTML5 validation tools You can download the W3C markup validator, but it is a pain trying to use it locally [4]. Ditto validator.nu [5]. Both of them are designed to be used as web services running under a web server, rather than as a simple command line app. I have got the latter one working with my 'django-output-validator' app, and it isn't too bad, but it is significantly harder than, for example, using the 'validate' binary from Debian package wdg-html-validator. It depends on whether people are already accustomed to using web services for validation. It is hard to know when this will be fixed, if ever, due to 1). It does seem like validation is becoming a much less useful thing anyway - what you really need to know is whether your document is going to be 'well enough' supported by browsers, which cannot be answered by validation. However, there will be some customers who require HTML validity (especially for WCAG and Section 508), and I for one would prefer it. If you take the approach of 'valid until proved otherwise', which I think is sensible, then knowing that 100% of output is valid is perhaps not too big an issue. 3) Potential problems if people have made use of actual XML features and use elements from other namespaces e.g. MathML/SVG/VML in pages that currently have XHTML doctypes, and need these features to work in browsers that support XHTML but not HTML5. I haven't done enough research to know which browser combinations are likely to be affected. Modern browsers have increasing support for MathML/SVG in HTML5 documents, and I suspect that in the vast majority of cases people are already using more portable and capable alternatives that won't break if we switch to HTML5 e.g. MathJax or <embed> for SVG, Did I miss anything? Overall, I think the advantages outweigh the disadvantages, that we have to make the move sometime, and now is about the right time, or perhaps slightly late. Regards, Luke [1] http://groups.google.com/group/django-developers/msg/a65fbbc8effcd914 [2] http://groups.google.com/group/django-developers/browse_thread/thread/cbb3aee22a0f8918/524255c10d3d86dc [3] http://wiki.whatwg.org/wiki/FAQ#When_will_HTML5_be_finished.3F [4] http://stackoverflow.com/questions/1701934/how-do-i-use-a-perl-cgi-locally-without-using-curl-and-apache2 [5] http://about.validator.nu/#src -- "If something is hard, it's not worth doing." (Homer Simpson) Luke Plant || http://lukeplant.me.uk/ -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.
diff -r d82edb1ca09f django/contrib/admin/templates/admin/base.html --- a/django/contrib/admin/templates/admin/base.html Mon Mar 28 16:11:40 2011 +0000 +++ b/django/contrib/admin/templates/admin/base.html Mon Mar 28 17:29:16 2011 +0100 @@ -1,5 +1,5 @@ -{% load url from future %}<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ LANGUAGE_CODE|default:"en-us" }}" xml:lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}> +{% load url from future %}<!DOCTYPE html> +<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}> <head> <title>{% block title %}{% endblock %}</title> <link rel="stylesheet" type="text/css" href="{% block stylesheet %}{% load adminmedia %}{% admin_media_prefix %}css/base.css{% endblock %}" /> diff -r d82edb1ca09f django/contrib/comments/templates/comments/400-debug.html --- a/django/contrib/comments/templates/comments/400-debug.html Mon Mar 28 16:11:40 2011 +0000 +++ b/django/contrib/comments/templates/comments/400-debug.html Mon Mar 28 17:29:16 2011 +0100 @@ -1,5 +1,5 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> +<!DOCTYPE html> +<html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>Comment post not allowed (400)</title> diff -r d82edb1ca09f django/contrib/comments/templates/comments/base.html --- a/django/contrib/comments/templates/comments/base.html Mon Mar 28 16:11:40 2011 +0000 +++ b/django/contrib/comments/templates/comments/base.html Mon Mar 28 17:29:16 2011 +0100 @@ -1,5 +1,5 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> +<!DOCTYPE html> +<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>{% block title %}{% endblock %}</title> diff -r d82edb1ca09f django/contrib/databrowse/templates/databrowse/base.html --- a/django/contrib/databrowse/templates/databrowse/base.html Mon Mar 28 16:11:40 2011 +0000 +++ b/django/contrib/databrowse/templates/databrowse/base.html Mon Mar 28 17:29:16 2011 +0100 @@ -1,5 +1,5 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ LANGUAGE_CODE|default:"en-us" }}" xml:lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}> +<!DOCTYPE html> +<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}> <head> <title>{% block title %}{% endblock %}</title> {% block style %} diff -r d82edb1ca09f django/contrib/flatpages/tests/templates/flatpages/default.html --- a/django/contrib/flatpages/tests/templates/flatpages/default.html Mon Mar 28 16:11:40 2011 +0000 +++ b/django/contrib/flatpages/tests/templates/flatpages/default.html Mon Mar 28 17:29:16 2011 +0100 @@ -1,5 +1,4 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" - "http://www.w3.org/TR/REC-html40/loose.dtd"> +<!DOCTYPE html> <html> <head> <title>{{ flatpage.title }}</title> diff -r d82edb1ca09f django/views/csrf.py --- a/django/views/csrf.py Mon Mar 28 16:11:40 2011 +0000 +++ b/django/views/csrf.py Mon Mar 28 17:29:16 2011 +0100 @@ -7,7 +7,7 @@ # other way of making it available independent of what is in the settings file. CSRF_FAILRE_TEMPLATE = """ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> diff -r d82edb1ca09f django/views/debug.py --- a/django/views/debug.py Mon Mar 28 16:11:40 2011 +0000 +++ b/django/views/debug.py Mon Mar 28 17:29:16 2011 +0100 @@ -311,7 +311,7 @@ # TECHNICAL_500_TEMPLATE = """ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<!DOCTYPE HTML> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> @@ -770,7 +770,7 @@ """ TECHNICAL_404_TEMPLATE = """ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> @@ -842,7 +842,7 @@ """ EMPTY_URLCONF_TEMPLATE = """ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<!DOCTYPE html> <html lang="en"><head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="robots" content="NONE,NOARCHIVE"><title>Welcome to Django</title> diff -r d82edb1ca09f django/views/static.py --- a/django/views/static.py Mon Mar 28 16:11:40 2011 +0000 +++ b/django/views/static.py Mon Mar 28 17:29:16 2011 +0100 @@ -65,8 +65,8 @@ DEFAULT_DIRECTORY_INDEX_TEMPLATE = """ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<!DOCTYPE html> +<html lang="en"> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Language" content="en-us" /> diff -r d82edb1ca09f docs/ref/contrib/flatpages.txt --- a/docs/ref/contrib/flatpages.txt Mon Mar 28 16:11:40 2011 +0000 +++ b/docs/ref/contrib/flatpages.txt Mon Mar 28 17:29:16 2011 +0100 @@ -158,8 +158,7 @@ .. code-block:: html+django - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" - "http://www.w3.org/TR/REC-html40/loose.dtd"> + <!DOCTYPE html> <html> <head> <title>{{ flatpage.title }}</title> diff -r d82edb1ca09f docs/topics/templates.txt --- a/docs/topics/templates.txt Mon Mar 28 16:11:40 2011 +0000 +++ b/docs/topics/templates.txt Mon Mar 28 17:29:16 2011 +0100 @@ -259,9 +259,8 @@ It's easiest to understand template inheritance by starting with an example:: - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <!DOCTYPE html> + <html lang="en"> <head> <link rel="stylesheet" href="style.css" /> <title>{% block title %}My amazing site{% endblock %}</title> @@ -313,9 +312,8 @@ template. Depending on the value of ``blog_entries``, the output might look like:: - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <!DOCTYPE html> + <html lang="en"> <head> <link rel="stylesheet" href="style.css" /> <title>My amazing blog</title> diff -r d82edb1ca09f docs/topics/testing.txt --- a/docs/topics/testing.txt Mon Mar 28 16:11:40 2011 +0000 +++ b/docs/topics/testing.txt Mon Mar 28 17:29:16 2011 +0100 @@ -615,7 +615,7 @@ 200 >>> response = c.get('/customer/details/') >>> response.content - '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...' + '<!DOCTYPE html...' As this example suggests, you can instantiate ``Client`` from within a session of the Python interactive interpreter.