Page ClientSideInclude.
httpsubst.js
What if a web page could me made from parts in other pages?
httpsubst.js is an Open Source JavaScript tool to compose HTML pages using other pages.
This is known as Client Side Include, aka HTML Link Inlining, aka in-place substitution, aka Mashups. The scientific name is Transclusion http://en.wikipedia.org/wiki/Transclusion
June 2007
Download Javascript file httpsubst.js
Source code contains a lot of comments, you may want to build a minimized version. Using some tools I got from about 18Kb down to 6kb (http://fmarcia.info/jsmin/test.html) or even 4Kb (http://dean.edwards.name/packer/). Beware: I haven't tested the results.
Examples
1) Here is an example using Google Page Creator: http://jeanhuguesrobert.googlepages.com/home2
2) Here is another example, a local example, in this Wiki site, in this very ClienSideInclude page actually, using page Httpsubst MotDuJour.
HttpsubstMotDuJour
Documentation
Extracted from the source code.
1) Template Mode.
By default, when httpsubst.js file is included in the body of an HTML
page, a link inlining occurs after the page is loaded.
ToDo: What if script is referenced in head vs body section of HTML page?
A - I provide multiple ways to specify links to inline because there are
often limitations over what users have full access to.
Hence inlined links are those *HTML A links* that either:
* have "httpsubst" inside the "id" attribute of the A element,
* or have "httpsubst" inside the "class" attribute,
* or those links that include "httpsubst" somewhere in the href url.
That "httpsubst" part of the url is removed before the url is used.
* or A links that contain some text element starting with "httpsubst".
* If text follows, it is a tag/regular-expr for the included content.
Please use whatever method is available to you ; class is best I guess.
B - Found A link elements are then replaced by pieces of content from url
linked pages. Links inlining is then done again in that new content.
What part is extracted depends on the "tag" used, see below.
2) API Mode. httpsubst( node, url, tag, dont_parse, dont_script);
You may use this function to replace one or many DOM elements using
the content of some url referenced external content.
Note: httpsubst( { node: xx, url: yy, ... works too, keyword params style.
* node. This parameter is the node element to modify.
If node is a compound element then it is all sub A elements in it that
will be processed, like in Template Mode, unless an url is specified.
* url. This is where to find content to change the node to modify.
When url is null/undefined, Template Mode is activated to figure it out.
* tag. This is delimiter for the "to be included" section of the target
page to use for inlining. See below.
* dont_parse. When false, newly included content is processed again
as if it were a template (hence some recursivity).
* dont_script. Unless specified otherwise, new content is searched
for scripts to evaluate. See also below about httpsubst.thisNode.
3) What is extracted from the sub pages.
It depends on the value of the so-called "tag".
* A - '', empty string. Simple. It is the full received text that is used.
* B - "body", Boby special case. It is the HTML body that is used.
* C - "frame", iframe special case. The whole page will be used in a
* distinct iframe, of fixed size 192 pixels height. Please note that
* all cross-domain reference end up as iframes for security reasons.
* D - null or undefined. Tag is first set to the default value: "httpsubst"
and then we get to case D below.
* E - "something". Tag is expected to somehow "enclose" the fragment to
to extract. I try multiple enclosing styles:
* 1 - tag is found on 2 newline terminated lines of text. In that
case it is text that is in between these 2 lines that is kept.
* 2 - tag is there twice but not on separate lines of text. This is a
poor man's case where every single character between the two tags
is kept. Caveat: This may easly include unbalanced HTML tags.
* 3 - tag is a regular expression. In that case it is the first match
that is kept. This is the most complex/powerfull mode. Remember
to use ([\S\s]*) instead of usual (.*), that's a pitfall (I go hurt).
When tag is not "found" in sub page, it is the page's body that is used,
unless that part cannot be extracted too, in which case it is the full
text that is kept, intact (you can breath now).
If the tag includes "eval" then the content is assumed to be some
JavaScript code to execute. eval() is called upon that code. While
it executes, this code can access httpsubst.thisNode to know about
the DOM node where the script was found.
4) Misc
Configurability
* httpsubst_api = true; Use this to prevent the default Template
Mode inlining that occurs when httpsubst.js is loaded.
* httpsubst.debug = true; Turns tracing on.
* httpsubst.log = alert; Defines Function to issue debug traces.
* Defaults to console.log() if using Firebug.
* httpsubst.err = alert; Defines Function to signal errors.
* Defaults to console.error() if using Firebug.
* httpsubst.loadMsg = "hidden"; Use this to have the visibily set
to "hidden" while new content is queried. One may also specify
an HTML string, but it may or may not work depending on the
type of element that encloses the inlined A links.
* Please note that all these configuration parameters must be
set *after* httpsubs.js is loaded. httpsubst_api is the
exception, it can/should be set *before* httpsubs.js is loaded.
* httpsubst( "version") returns the version number.
* httpsubst( "version", id) sets the desired API. So far id
is actually ignored, but mechanism is future proof.
Bugs
* On Opera the retrieved content is not available when the HTTP status is
404 (vs 200). This a known Opera bug.
Security:
* The code uses XMLHTTP style requests. As a result, only requests
to the same domain can be issued.
* ToDo: when "scripts eval" will be implemented (if ever) some people
will most probably feel better turning it off.
Source code (for the curious)
httpsubst.js
Future, no
I wished that the next step would be some cross domain scheme.
October 7th 2008
A new technique for cross-domain requests recently emerged. The idea is to use the window.name attribute of an iframe to communicate the received content to the requesting page. See a Dojo[implementation]
January 15th 2008
Firefox 3 will implement a solution to enable cross domain scripting. It requires access to either the header section of the HTML document or the access to the XML document. See Cross-Site XMLHttpRequest in Firefox 3 at Ajaxian.
November 21th 2007
I give up. Iframes don't work. Things are done in such a ways that parent window can never communicate with included frame, even if they both agree on a very secure way to communicate. Purely paranoid.
There exists a solution using the Dojo framework and "fragments". Work is being done on the "mashups" related subject. See mashupOS for example. See also the HTML 5 Draft that acknowledges the issue and propose a solution.
With some DNS trickery sites can collaborate, but this is server sided. See http://www.alexpooley.com/2007/08/07/how-to-cross-domain-javascript/
Douglas Crockford did an interesting presentation about Javascript, mashups and security: Gears and the Mashup Problem video
About templating, see the mjt client side Javascript system at http://www.mjtemplate.org/
October 28th 2007
Look here for a security workaround in Firefox only.
About this page
Allez savoir pourquoi personne à l'époque au W3C n'a pensé utile d'introduire le moyen de composer une page HTML avec le contenu d'autres pages. C'était pourtant pas sorcier d'avoir un < inc href="included.html"> !
200 ans plus tard la situation n'a pas évolué (presque pas, il y a les frames et les iframes...). Mais on peut + ou - s'en tirer avec Javascript. Moralité : TOUJOURS embarquer un language dans le produit fini. Moralité 2 : Si le produit fini part dans l'espace, vérifier que le dit language a un accès r/w complet à la mémoire (mais je m'égare).
Donc, j'ai cherché et trouvé ça autour de XMLHTTP, aka Ajax :
Je voulais inclure, en partie, une ou plusieurs pages de ce site dans d'autres pages de ce même site. Pour cela, dans chaque page :
- Une fois la page chargée, trouver les inclusions.
- Pour chaque inclusion
- Demander la page à inclure
- Quand la réponse arrive extraire le contenu désiré de la page
- Remplacer la référence vers la page à inclure par le contenu de cette page au sein de la page initiale
- Exécuter ou pas les scripts présent dans le contenu inclu (ça reste à faire)
Pour des raisons de sécurité (à la noix) XMLHTTPRequest ne marche pas "cross-domain", on ne pourra donc qu'inclure des pages venant du même domaine/site. Sauf si "Subspace: Secure Cross-Domain Communication for Web Mashups" (PDF), par exemple, permet de s'en sortir.
Nota : Même avec des iframes on est bloqué, pour des questions de "sécurité" paranoïaques. Rien n'y fait, la page inclue ne peut pas communiquer avec la page contenante, même si elles sont toutes deux consentantes. Comment casser un truc qui marche... Un jour il faudra enfermer les paranoïaques ensembles, ça nous fera des vacances.
-- AjouterUnCommentaire
|