Пусть у нас есть простенький хтмльчик index1.htm
Как известно, хтмл поддерживает инклуды только через iframe/object, но с ними не очень удобно работать из яваскрипта.
Можно, конечно, прописать в каждую подключаемую страницу скрипт типа такого
Он переносит своё содержимое в родительский документ и удаляет фрейм. Но в случае отключённоо яваскрипта мы получим окошко ифрейма не подстраивающееся под размер содержимого.
В XHTML2 пояилась интересная возможность — аттрибут src можно задавать любому элементу и содержимое документа на который он указывает будет всталено вместо содержимого элемента. Напишем index2.htm
Проверили — не работает. Оживить её можно с помощью яваскрипта, который опять же может быть отключён, но это уже не так фатально — пользователю будет показана ссылка на подключаемый файл.
Но мы поступим круче и обойдёмся без яваскрипта. А поможет нам в этом xsl преобразование, накладывающееся само на себя. Напишем index2.xml, который будет ни чем иным, как index.htm обёрнутым в специальную волшебную обёртку.
Доктайп тут выполняет две функции:
1. он указывает xml-процессору, что аттрибут id в t:stylesheet является идентификатором, что позволяет использовать его при указании xsl-преобразования.
2. Если документ будет отдан как text/html, то браузет всё ж будет рендерить страницу в режиме соответствия стандартам. В t:output мы прописываем доктайп по той же причине, только для случая, когда документ был отдан как xml и xslt преобразовал себя в html.
Первый шаблон матчится на все узлы и рекурсивно их копирует. Второй — матричится на корень и пропускает xslt тэги, сразу переходя к выводу html. Последнее правило просто содержит html с инклудами. Имя его не имеет никакого значения.
Если проверить сейчас это в браузере, то никаких отличий быть не должо. Однако, если добавить ещё один шаблон, то инклуды внезапно заработают.
Примечательно, что инклудить таким образом можно как xml типа index2.xml, так и html типа index1.htm
Напишем index3.xml, который инклудит index2.xml
Для роботов и убогих мобильных браузеров страницы можно просто отдавать как text/html и тогда вместо вставляемого файла будет рисоваться ссылка на него.
Совместимость: ie6+, ff3+, opera10+, webkit?+
<!DOCTYPE html><br><html><br> <head><br> <title>Xbrowser HTML includes</title><br> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><br> </head><br> <body><br> <h1>First file</h1><br> </body><br></html>
Как известно, хтмл поддерживает инклуды только через iframe/object, но с ними не очень удобно работать из яваскрипта.
Можно, конечно, прописать в каждую подключаемую страницу скрипт типа такого
new function(){<br> var frame= window.frameElement<br> if( !frame ) return<br> var parent= frame.parentNode<br> var body= document.getElementsByTagName( 'body' )[0]<br> var child;<br> while( child= body.firstChild ) parent.insertBefore( child, frame )<br> parent.removeChild( frame )<br>}
Он переносит своё содержимое в родительский документ и удаляет фрейм. Но в случае отключённоо яваскрипта мы получим окошко ифрейма не подстраивающееся под размер содержимого.
В XHTML2 пояилась интересная возможность — аттрибут src можно задавать любому элементу и содержимое документа на который он указывает будет всталено вместо содержимого элемента. Напишем index2.htm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 2.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml2.dtd"><br><html><br> <head><br> <title>Xbrowser HTML includes</title><br> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><br> </head><br> <body><br> <h1>Second file</h1><br> <div src="index1.xml" srctype="text/xml"><br> <a href="index1.xml">link 2 first file</a><br> </div><br> </body><br></html>
Проверили — не работает. Оживить её можно с помощью яваскрипта, который опять же может быть отключён, но это уже не так фатально — пользователю будет показана ссылка на подключаемый файл.
Но мы поступим круче и обойдёмся без яваскрипта. А поможет нам в этом xsl преобразование, накладывающееся само на себя. Напишем index2.xml, который будет ни чем иным, как index.htm обёрнутым в специальную волшебную обёртку.
<!DOCTYPE t:stylesheet [ <!ATTLIST t:stylesheet id ID #REQUIRED> ]> <br><?xml-stylesheet type="text/xsl" href="#t:stylesheet"?><br><t:stylesheet id="t:stylesheet" version="1.0" xmlns:t="http://www.w3.org/1999/XSL/Transform"><br> <t:output method="html" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" /><br> <t:template match=" @* | node() "><br> <t:copy><br> <t:apply-templates select=" @* | node() " /><br> </t:copy><br> </t:template><br> <t:template match=" / "><br> <t:apply-templates select=" document( '#t:stylesheet' )//html " /><br> </t:template><br> <t:template name="content"><br> <html><br> <head><br> <title>Xbrowser HTML includes</title><br> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><br> </head><br> <body><br> <h1>Second file</h1><br> <div src="index1.htm" srctype="text/xml"><br> <a href="index1.htm">link 2 first file</a><br> </div><br> </body><br> </html><br> </t:template><br></t:stylesheet>
Доктайп тут выполняет две функции:
1. он указывает xml-процессору, что аттрибут id в t:stylesheet является идентификатором, что позволяет использовать его при указании xsl-преобразования.
2. Если документ будет отдан как text/html, то браузет всё ж будет рендерить страницу в режиме соответствия стандартам. В t:output мы прописываем доктайп по той же причине, только для случая, когда документ был отдан как xml и xslt преобразовал себя в html.
Первый шаблон матчится на все узлы и рекурсивно их копирует. Второй — матричится на корень и пропускает xslt тэги, сразу переходя к выводу html. Последнее правило просто содержит html с инклудами. Имя его не имеет никакого значения.
Если проверить сейчас это в браузере, то никаких отличий быть не должо. Однако, если добавить ещё один шаблон, то инклуды внезапно заработают.
<t:template match=" *[ @src and contains( @srctype, 'xml' ) ] "><br> <t:copy><br> <t:apply-templates select=" @* " /><br> <t:apply-templates select=' document( @src )//html/body/* ' /><br> </t:copy><br></t:template>
Примечательно, что инклудить таким образом можно как xml типа index2.xml, так и html типа index1.htm
Напишем index3.xml, который инклудит index2.xml
<!DOCTYPE t:stylesheet [ <!ATTLIST t:stylesheet id ID #REQUIRED> ]><br><?xml-stylesheet type="text/xsl" href="#t:stylesheet"?><br><t:stylesheet id="t:stylesheet" version="1.0" xmlns:t="http://www.w3.org/1999/XSL/Transform"><br> <t:output doctype-public="-//W3C//DTD XHTML 2.0//EN" doctype-system="http://www.w3.org/MarkUp/DTD/xhtml2.dtd" /><br> <t:template match=" @* | node() "><br> <t:copy><br> <t:apply-templates select=" @* | node() " /><br> </t:copy><br> </t:template><br> <t:template match=" *[ @src and contains( @srctype, 'xml' ) ] "><br> <t:copy><br> <t:apply-templates select=" @* " /><br> <t:apply-templates select=' document( @src )//html/body/* ' /><br> </t:copy><br> </t:template><br> <t:template match=" / "><br> <t:apply-templates select=" document( '#t:stylesheet' )//html " /><br> </t:template><br> <t:template name="content"><br> <html><br> <head><br> <title>Xbrowser HTML includes</title><br> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><br> </head><br> <body><br> <h1>Third file</h1><br> <div src="index2.xml" srctype="text/xml"><br> <a href="index2.xml">link 2 second file</a><br> </div><br> </body><br> </html><br> </t:template><br></t:stylesheet>
Для роботов и убогих мобильных браузеров страницы можно просто отдавать как text/html и тогда вместо вставляемого файла будет рисоваться ссылка на него.
Совместимость: ie6+, ff3+, opera10+, webkit?+