Changing the defaults for empty tag shorthand in XML

This commit is contained in:
Jay McCarthy 2012-01-25 16:09:09 -07:00
parent 41a64cbbd8
commit ce73175427
4 changed files with 50 additions and 28 deletions

View File

@ -60,6 +60,7 @@
(define xml-tests
(test-suite
"XML"
#:before (λ () (empty-tag-shorthand 'always))
(test-suite
"Legacy tests"

View File

@ -76,7 +76,7 @@ easily built into an application via URLs.
@section{My browser displays my page strangely: my CSS is ignored, sections are missing, etc.}
@(require (for-label xml
web-server/http/response-structs))
web-server/http))
@(define xexpr @tech[#:doc '(lib "xml/xml.scrbl")]{X-expression})
@ -84,26 +84,45 @@ Most @web-server developers use @|xexpr|s for representing the
HTML of their page. However, @|xexpr|s only represent XML and HTML is not exactly
XML. This is a common source of problems.
For example, XML allows the "empty tag shorthand", e.g. @litchar{<img src='...' />},
on every tag, while HTML occasionally requires an end tag, e.g. @link["http://www.w3.org/TR/html401/interact/forms.html#h-17.7"]{TEXTAREA}.
Similarly, XML allows an end tag, e.g. @litchar{<img src='...'></img>}, on every tag, while
HTML occasionally forbides an end tag, e.g. @link["http://www.w3.org/TR/html401/struct/objects.html#h-13.2"]{IMG}.
(Of course, browsers do not necessarily implement their HTML parsing as specified and may be more or less lenient towards
XML-like HTML, so your test browser may not treat these forms as problematic.)
For example, XML allows the "empty tag shorthand", e.g. @litchar{<img
src='...' />}, on every tag, while HTML occasionally requires an end
tag,
e.g. @link["http://www.w3.org/TR/html401/interact/forms.html#h-17.7"]{TEXTAREA}.
Similarly, XML allows an end tag, e.g. @litchar{<img
src='...'></img>}, on every tag, while HTML occasionally forbides an
end tag,
e.g. @link["http://www.w3.org/TR/html401/struct/objects.html#h-13.2"]{IMG}.
(Of course, browsers do not necessarily implement their HTML parsing
as specified and may be more or less lenient towards XML-like HTML, so
your test browser may not treat these forms as problematic.)
Since the @web-server uses @racketmodname[xml] to format @|xexpr|s, it inherits @racketmodname[xml]'s default rendering behavior
in general and its use of "empty tag shorthand" in particular. @racketmodname[xml]'s is to always use this short hand. You
can change it with the @racket[empty-tag-shorthand] parameter.
Since the @web-server uses @racketmodname[xml] to format @|xexpr|s, it
inherits @racketmodname[xml]'s default rendering behavior in general
and its use of "empty tag shorthand" in
particular. @racketmodname[xml]'s default is always use the shorthand
with the tags from @racket[html-empty-tags] and never otherwise. This
list should contain the W3C's approved list. You can change it with
the @racket[empty-tag-shorthand] parameter.
You can also change your @xexpr so that an end tag is forced. For example, @racket['(textarea [(name "text")])] renders as
@litchar{<textarea name="text" />}, while @racket['(textarea [(name "text")] "")] renders as
@litchar{<textarea name="text"></textarea>}, because of the string content in the @|xexpr|.
You can also change your @xexpr so that an end tag is forced. For
example, @racket['(textarea [(name "text")])] renders as
@litchar{<textarea name="text" />}, while @racket['(textarea [(name
"text")] "")] renders as @litchar{<textarea name="text"></textarea>},
because of the string content in the @|xexpr|. In this case, the end
tag will always be present regardless of the value of
@racket[empty-tag-shorthand]. It is not possible to force the other
possibility; i.e., never include an end tag.
You may think the @web-server could do a better job advertising that the contents it serves is more like XML by default. Unfortunately,
browser support for such @link["http://www.w3.org/TR/xhtml-media-types/#media-types"]{advertisement} is @link["http://www.w3.org/MarkUp/2004/xhtml-faq#ie"]{lacking}.
You can use @racket[make-xexpr-response] to easily customize your application's MIME type and response headers.
You may think the @web-server could do a better job advertising that
the contents it serves is more like XML by default. Unfortunately,
browser support for such
@link["http://www.w3.org/TR/xhtml-media-types/#media-types"]{advertisement}
is @link["http://www.w3.org/MarkUp/2004/xhtml-faq#ie"]{lacking}. You
can use @racket[response/xexpr] to easily customize your
application's MIME type and response headers.
Finally, you may find Web browser inspectors such as the Safari Inspector, Firebug, and the Google Chrome error console to be useful
Finally, you may find Web browser inspectors such as the Safari
Inspector, Firebug, and the Google Chrome error console to be useful
tools in identifying offending tags.
@section{How do I use templates ``dynamically"?}

View File

@ -9,15 +9,17 @@
[empty-tag-shorthand (parameter/c (or/c (symbols 'always 'never) (listof symbol?)))]
[html-empty-tags (listof symbol?)])
(define html-empty-tags
'(param meta link isindex input img hr frame col br basefont base area))
;; (empty-tag-shorthand) : (U 'always 'never (listof Symbol))
(define empty-tag-shorthand
(make-parameter 'always
(lambda (x)
(if (or (eq? x 'always) (eq? x 'never) (and (list? x) (andmap symbol? x)))
x
(error 'empty-tag-shorthand "expected 'always, 'never, or a list of symbols: received ~e" x)))))
(define html-empty-tags '(param meta link isindex input img hr frame col br basefont base area))
(make-parameter
html-empty-tags
(lambda (x)
(if (or (eq? x 'always) (eq? x 'never) (and (list? x) (andmap symbol? x)))
x
(error 'empty-tag-shorthand "expected 'always, 'never, or a list of symbols: received ~e" x)))))
;; gen-write/display-xml/content : (Nat Output-port -> Void) -> Content [Output-Port]-> Void
(define (gen-write/display-xml/content dent)

View File

@ -335,14 +335,14 @@ for elements that have no content.
When the parameter is set to @racket['always], the abbreviated
notation is always used. When set of @racket['never], the abbreviated
notation is never generated. when set to a list of symbols is
provided, tags with names in the list are abbreviated. The default is
@racket['always].
provided, tags with names in the list are abbreviated.
The abbreviated form is the preferred XML notation. However, most
browsers designed for HTML will only properly render XHTML if the
document uses a mixture of the two formats. The
@racket[html-empty-tags] constant contains the W3 consortium's
recommended list of XHTML tags that should use the shorthand.}
recommended list of XHTML tags that should use the shorthand. This
list is the default value of @racket[empty-tag-shorthand].}
@defthing[html-empty-tags (listof symbol?)]{
@ -509,4 +509,4 @@ This library provides a simple path query library for X-expressions.
(se-path* '(p #:class) some-page)
(se-path*/list '(body) some-page)
(se-path*/list '() some-page)
]
]