This plug-in allows to display a website stored in Nuxeo either as:
-
A
Folderish
Document containing the site, with relative paths. So for example, an index.html file with animg
tag whosesrc
attribute is"img/logo.png"
, and at first level of the Document, there is animg
folder containing the logo.png Picture document -
Or a non
Folderish
document whosefile:content
field contains a blob that can be unzipped as a website (typically a .zip file). Please read below, "WARNING About the Zip Format" -
Notice: It will also display the minisite, if any, when the document is a
Folderish
whose content does not have any html file to display at first level and if thisFolderish
also have zip file in it'sfile
schema. -
Also, this is about previewing The preview is displayed in the context of the Nuxeo application. This means, some JavaScript or access to other website, if any, may fail (typically because of CORS)
Important
Please read all the WARNINGS below:
- Security Warning
- About the
Note
document type - About the Zip Format
- Relative Paths and Max Length of
name
The plug-in creates a WebEngine module allowing to access the embedded website via a URL. The name of the module (in the URLs) is WSP
(WebSitePreview).
-
In order to be as easy possible to use, the main url must end with
index.html
, whatever the real name of your main html file. -
So, to access the preview(*), the URL to use is:
{server:port}/nuxeo/site/WSP/main-parent-doc-id/index.html
This URL will typically be used in the UI using an
iframe
-
For example, say you have a Folderish document, named "My Site", whose
id
is1234-5678-9ABC-DEF0
, and you are testing on your localhost, you can display the preview using this URL:http://localhost:8080/nuxeo/site/WSP/1234-5678-9ABC-DEF0/index.html
.The exact same URL is used if instead of a
Folderish
containing all the website as Nuxeo documents, it is aFile
whosefile:content
holds a zip containing the website -
The plugin contributes the
Website
facet:- Because not every
Folderish
and not every .zip host a website - So you can dynamically add/remove (using the
Document.AddFacet
andDocument.RemoveFacet
operations) this facet from your documents for quick test to display a "preview" button in the UI for example - IMPORTANT: The plugin does not add/remove this facet at anytime, it is for you to use.
- A typical example would be a button in the UI, like "This is a website". The user clicks it and you run the
Document.Addfacet
operation to add theWebsite
facet. - This could also be done automatically in a listener depending on some metadata and rules, and if the
Document.HasWebsite
operation returnstrue
(see below).
- A typical example would be a button in the UI, like "This is a website". The user clicks it and you run the
- Because not every
(*) Assuming current user is logged in and has enough rights to at least read the blobs.
Whatever the source (a Folderish
or a .zip), the plugin searches for a main html file using this algorithm:
- Whatever the name, it must be at first level, the plugin does not search in nested folders
- If, at first level, one file is
index.html
, the document is considered being a website and this file will be returned at the first preview - If there is no
index.html
file, the plugin searches for any other .html and returns the first it finds, to be used at first display - If there is no .html file at all at first level, the plug-in returns a 404 error.
WARNING
This means that if the source document contains at least one html document at first level, will be seen as a mini website. The preview will display the HTML, but the result is unpredictable if it is not website with relative paths for sub-elements.
This is why you should use the Website
facet and add your preview only when it is relevant
The plugin provides the following operation(s):
#### Document.HasWebsite
input
is a documentoutput
is the document, unchanged- The operation sets the
WSP_hasWebsite
boolean Context Variable with the result: - If the Document has the
Website
facet,WSP_hasWebsite
is set totrue
- Else, if it is a
Folderish
document with an html child at first level,WSP_hasWebsite
is set totrue
- Else, it the document has the
file
schema andfile:content
can be unzipped and contains an html file at first level,WSP_hasWebsite
is set totrue
- Else,
WSP_hasWebsite
is set tofalse
.
- First, create an element (in Studio Designer > Resources) with an iframe and set the src of the iframe to the correct url. For example:
<dom-module id="my-website-preview">
<template>
<style>
*[role=widget] {
padding: 5px;
}
iframe {
position: absolute;
width: 95%;
height: 90%;
border: 2 2 2 2;
}
</style>
<!--
It is important to filter with the facet: If this element is displayed as a tab, calls to the server
will always be done for evey document _before_ applying WebUI filter. So, you display Root, Domain, ...
=> The plugin is called and tries to get an index.html file.
This is not efficient => you should show/hide the iframe here to avoid these useless calls
-->
<iframe src="/nuxeo/site/WSP/[[document.uid]]/index.html"></iframe>
</template>
<script>
Polymer({
is: 'my-website-preview',
behaviors: [Nuxeo.LayoutBehavior],
properties: {
document: {
type: Object
}
}
});
</script>
</dom-module>
- Create a Document Page tab (In Studio Designer > UI) displaying this element, with the correct filter (typically, if the document has the
Website
facet)
When using a zip file, it must not be built with a tool that prefixes the paths of every item. For example, if you zip the mysite
folder containing...
img
logo.png
index.html
otherpage.html
... the zip file must not have a TOC prefixing every path with mysite
. The list of files in the zip must be...
img/
img/logo.png
index.html
otherpage.html
...and not:
mysite/img/
mysite/img/logo.png
mysite/index.html
mysite/otherpage.html
When using the plugin to display the ocntent of a Folderish
, we strongly recommand to make sure Nuxeo dose not create a Note
document type for your HTML. Nuxeo may automatically strip some HTML content form the HTML, and the preview will display poorly.
So, we recommend to add the following XML extension in your Studio project, to disable the creation of Note
when you drag-drop and HTML file. It will instead create a File
, which is good.
<extension target="org.nuxeo.ecm.platform.filemanager.service.FileManagerService"
point="plugins">
<plugin name="NoteImporter" enabled="false"/>
</extension>
This warning applies only when previewing a Folderish
and its content.
In this context, make sure the relative path is valid. Nuxeo truncates/modifies the name
(what is used in the URL) when they are too long. For example, if your file name is "my-long-file-name-for-a-js-but-like-very-very-very-long-and-could-be-longer.js", when created (or imported) Nuxeo will truncate, by default, to "my-long-file-name-for-a-" (24 chars). So, when requesting it from its full name, it will fail.
You can change this value by using the nuxeo.path.segment.maxsize
configuration parameter. Either in nuxeo.conf
:
nuxeo.path.segment.maxsize=YOUR_VALUE
Or via XML:
<extension target="org.nuxeo.runtime.ConfigurationService" point="configuration">
<property name="nuxeo.path.segment.maxsize">YOUR_VALUE</property>
</extension>
Notice the plugin tries to workaround this in a single attempt. In the previous example, if the path is...
/domain/aworkspace/afolder/yoursite/main/js/my-long-file-name-for-a-js-but-like-very-very-very-long-and-could-be-longer.js
...if Nuxeo throws a DocumentNotFoundException
, the plugin will search inside /domain//aworkspace/afolder/yoursite/main/js
for a Document whose dc:title
is "my-long-file-name-for-a-js-but-like-very-very-very-long-and-could-be-longer.js".
The plugin sends the files as they are stored (either as single Nuxeo Document or inside the .zip file). This means no sanitizing is done, the JavaScript is not filtered and is sent as is.
If there is any risk of a user uploading a website that contains some malicious JavaScript (like getting the cookies to steel the session), then we recommend to add configuration to approve/reject the document before making it available.
The plugin could also be forked and sanitizing the JavaScript can be done (Nuxeo has APIs for this purpose). This means the plugin would then send html files that contain no <script>
tag at all for example.
These features are not part of the Nuxeo Production platform.
These solutions are provided for inspiration and we encourage customers to use them as code samples and learning resources.
This is a moving project (no API maintenance, no deprecation process, etc.) If any of these solutions are found to be useful for the Nuxeo Platform in general, they will be integrated directly into platform, not maintained in this repository.
Contributors: Thibaud Arguillere (https://github.com/ThibArg)
Nuxeo, developer of the leading Content Services Platform, is reinventing enterprise content management (ECM) and digital asset management (DAM). Nuxeo is fundamentally changing how people work with data and content to realize new value from digital information. Its cloud-native platform has been deployed by large enterprises, mid-sized businesses and government agencies worldwide. Customers like Verizon, Electronic Arts, ABN Amro, and the Department of Defense have used Nuxeo's technology to transform the way they do business. Founded in 2008, the company is based in New York with offices across the United States, Europe, and Asia. Learn more at www.nuxeo.com.