This chapter presents the concepts of schemas, facets and document types, which are used to define documents.
In Nuxeo Platform, a fundamental entity is the document. A file, a note, a vacation request, an expense report, but also a folder, a forum, can all be thought of as documents. Objects that contain documents, like a folder or a workspace, are also themselves documents.
Any given document has a document type. The document type is specified at creation time, and does not change during the lifetime of the document. When referring to the document type, a short string is often used, for instance "Note" or "Folder".
A document type is defined by several schemas. A schema represents the names and structure (types) of a set of fields in a document. For instance, a commonly-used schema is the Dublin Core schema, which specifies a standard set of fields used for document metadata like the title, description, modification date, etc.
In addition to the schemas that the document type always has, a given document instance can receive facets. A facet has a name, like "Downloadable" or "Commentable", and can be associated with zero or more schemas. When a document instance receives a facet, the fields of its schemas are automatically added to the document.
To create a new document type, we start by creating one or more schemas that the document type will use. The schema is defined in a .xsd file and is registered by a contribution to the schema extension point. The document type is then registered through a contribution to the doctype extension point which specifies which schemas it uses. Facets are also registered through the doctype extension point.
In addition to the structural definition for a document type, there's another registration at the UI level, through a different extension point, to define how a given document type will be rendered (its icon, layouts, default view, etc.).
The sections below describe how schemas, facets and document types are defined at a low level in Nuxeo Platform using XML configuration files. Unless you're an advanced user, it will be much simpler to use Nuxeo Studio to define them.
A schema describes the names and types of some fields. The name is a simple string, like "title", and the type describes what kind of information it stores, like a string, an integer or a date.
A schema is defined in a .xsd file and obeys the standard XML Schema syntax.
For example, we can create a schema in the schemas/sample.xsd file:
This schema defines two things:
an XML namespace that will be associated with the schema (but isn't used by Nuxeo Platform),
two elements and their type.
The two elements are sample1 and sample2. They are both of type "string", which is a standard type defined by the XML Schema specification.
A schema file has to be referenced by Nuxeo configuration to be found and used. The schema must be referenced in the schema extension point of the org.nuxeo.ecm.core.schema.TypeService component. A reference to a schema defines:
the schema name,
the schema location (file),
an optional (but recommended) schema prefix.
For example, in the configuration file OSGI-INF/types-contrib.xml (the name is just a convention) you can define:
We name our schema "sample", and the .xsd file is referenced through its path, schemas/sample.xsd. The schema is registered through the schema extension point of the Nuxeo component org.nuxeo.ecm.core.schema.TypeService. Our own extension component is given a name, org.nuxeo.project.sample.types, which is not very important as we only contribute to existing extension points and don't define new ones — but the name must be new and unique.
Finally, like for all components defining configuration, the component has to registered with the system by referencing it from the META-INF/MANIFEST.MF file of the bundle.
In our example, we tell the system that the OSGI-INF/types-contrib.xml file has to be read, by mentioning it in the Nuxeo-Component part of the META-INF/MANIFEST.MF:
You may need to override an existing schema defined by Nuxeo. As usual, this possible and you have to contribute a schema descriptor with same name. But you must also add an override parameter with value "true".
For instance, you can add your own parameters into the user.xsd schema to add the extra information stored into your ldap and fetch them and store them into the principal instance (that represents every user). The contribution will be something like:
Focus your attention on the override="true" that is often missing
You will need to improve the UI to also display your extra-informations...
A facet describes an aspect of a document that can apply to several document types or document instances. Facets can have zero, one or more schemas associated to them. Configuration is done in the doctype extension point of the same org.nuxeo.ecm.core.schema.TypeService component as for schemas.
For example, in the same OSGI-INF/types-contrib.xml as above, we add the following:
Facets can be used in two ways:
on document types, by adding the facet to the <doctype> element described below,
on document instances, by application code.
When a document's type or a document's instance has a facet, the document behaves normally with respect to the added schemas. Facets with no schemas are useful to mark certain types or certain document instances specially, for instance to add additional behavior when they are used.
Standard Nuxeo Platform facets are:
Folderish: special facet allowing the creation of children in this document,
Orderable: special facet allowing the children of a folderish type to be ordered,
Versionable: special facet marking the document type as versionable,
HiddenInNavigation: special facet for document types which should not appear in listings.
By itself, the schema is not very useful, it must be associated with a document type. This is done in the same doctype extension point as above. In this extension point, we define:
the document type to create,
which standard document type it extends (usually "Document" or "Folder"),
what schemas it contains,
what facets it has (this implicitly adds all the facet's schemas).
When extending a document type, all its schemas and facets are inherited as well.
For example, in the same OSGI-INF/types-contrib.xml as above, we add the following:
Here we specify that our document type "Sample" will be an extension of the standard system type "Document" and that it will be composed of three schemas, two standard ones and our specific one, and has one facet.
The standard schemas "common" and "dublincore" already contain standard metadata fields, like a title, a description, the modification date, the document contributors, etc. Adding it to a document type ensures that a minimal level of functionality will be present, and is recommended for all types.
UI Document Types
After the structural document type, a UI registration for our document type must be done for the type to be visible in the Nuxeo DM interface (or in other applications based on Nuxeo Platform). This is done through a contribution to the types extension point of the org.nuxeo.ecm.platform.types.TypeService component (which is a different component than for the structural types, despite also ending in TypeService).
For example, in OSGI-INF/ui-types-contrib.xml we will define:
The extension must be added to META-INF/MANIFEST.MF so that it will be taken into account by the deployment mechanism:
The type element will contain all the information for this type, described below.
The label, description, icon, bigIcon and category are used by the user interface, for instance in the creation page when a list of possible types is displayed.
label: a short name for the type.
description: a longer description of the type.
icon: a 16x16 icon path for the type, used in listings for instance. The path points to a resource defined in the Nuxeo WAR.
bigIcon: a 100x100 icon path for the type, used in the creation screen for instance.
category: a category for the type, used to separate types in different sections in the creation screen for instance.
Standard categories used in the Nuxeo DM interface are:
SimpleDocument: a simple document
Collaborative: a document or folder-like objects used for collaboration
SuperDocument: a structural document usually created by the system
Other categories can freely be defined.
The default-view tag specifies the name of the facelet to use to display this document. This corresponds to a file that lives in the webapp, by default view_documents.xhtml which is a standard view defined in the base Nuxeo Platform bundle. This standard view takes care of displaying available tabs and the document body according to the currently selected type.
Changing it is not advised unless extremely nonstandard rendering is needed.
The create-view and edit-view tags can point to a specific creation or edit facelets.
Proper defaults are used when these are not specified, so no need to add them to your type.
A layout is a series of widgets, which makes the association between the field of a schema with a JSF component. The layout is used by the standard Nuxeo modification and summary views, to automatically display the document metadata according to the layout rules.
The layouts section (with a final s) defines the layouts for the document type for a given mode.
Defaults mode are:
create for creation,
edit for edition,
view for view,
any for layouts that will be merged in all the other modes.
The layout names refer to layouts defined on another extension point. Please see the layouts section for more information.
The subtypes section defines a list of type elements for the document types that can be created as children objects of other document types. When defining a type, you can specify:
what child document types can be create in it,
in what parent document types it can be created.
This can also be defined for a pre-existing type, to add new allowed subtypes. Please make sure you require the components defining the pre-existing type to ensure a good merge of contributions.
For example, we can specify that the Sample type can be created in a Folder and a Workspace. Note that we define two new <type> sections here, we don't add this information in the <type id="Sample"> section.
It is also possible to define that some types will not be allowed as children in some cases (creation, copy/paste). To do that, a hidden attribute for the type element can be used.
The hidden cases are stored in a list, so if a check is needed for a hidden case, then the hidden cases list ought to be verified to check it contains that particular case.
The final OSGI-INF/ui-types-contrib.xml looks like: