Déclaration et modification d'un type de contenu


Le CMS Ametys supporte différents types de contenus (article, actualité, galeries photos, FAQ, ...). Les types de contenus disponibles dépendent des extensions (plugins) utilisés.

Les types de contenus les plus couramment utilisés sont décrits dans le Manuel Utilisateur.

Un type de contenu est un point d'extension multiple. Un intégrateur peut créer des nouveaux type de contenus (séminaire, poste, etc) suivant vos besoins.

  1. Général
  2. Les icônes ou glyphes
  3. Les attributs
    1. Déclaration simple
    2. Validation
    3. Widget de modification
    4. Attribut composite
    5. Les énumérations
    6. Les valeurs par défaut
    7. Restrictions
    8. Syntaxe historique
  4. Les propriétés
    1. Référencer un élément du modèle
    2. Pointer vers une classe
  5. Validation globale
  6. Les vues
    1. Syntaxe
    2. Vues jointées
    3. Syntaxe simplifiée
    4. Surcharge d'une vue
    5. Les vues obligatoires et optionnelles
    6. Syntaxe historique
  7. Les tags
  8. Héritage multiple
  9. Les types de contenus spécifiques
    1. Les rôles
    2. Les tables de référence
    3. Type de contenu privé
    4. Type de contenu abstrait
  10. Définition d'un nouveau type de contenu
    1. Définition dans le répertoire WEB-INF/param/content-types
    2. Définition dans un plugin
  11. Modification d'un type de contenu existant
    1. Modification dans le répertoire WEB-INF/param/content-types/_override
    2. Modification dans un plugin
    3. Ordre de prise en compte des surcharges
  12. Exemples de déclarations de types de contenus
    1. Exemple complet de déclaration d'un type contenu simple
    2. Exemples de modifications du type de contenu simple
  13. Indexation et recherche
    1. Propriété système fulltext
    2. Les facettes
  14. Le rendu graphique

 

Général

Un type de contenu est défini par:

  • Un identifiant unique
  • Un libellé
  • Une description
  • Le titre par défaut des contenus de ce type
  • Des icônes, glyph ou de taille 16x16, 32x32 et 48x48 pixels
  • Un droit (optionnel) pour restreinte la création du type de contenu aux personnes ayant droit
  • Un jeu d'attributs (ex: titre, description, image, fichiers, date, ...) typés.
  • Des propriétés (optionnel)
  • Des validateurs globaux (optionnel) pour définir des règles de validation entre plusieurs éléments (ex: startDate < endDate)
  • Des vues

Chaque vue définit la liste des attributs et propriétés qui lui sont nécessaires, parmi les attributs et propriétés du type contenus. Par exemple, une vue "abstract" (résumé) aura besoin des attributs titre et illustration, tandis qu'une vue "main" (complète) aura besoin de l'ensemble des attributs.

Un type de contenu est un point d'extension de type org.ametys.cms.contenttype.ContentTypeExtensionPoint. Sa déclaration doit respecté le format XML suivant:

Format XML de déclaration d'un type de contenu

<extension point="org.ametys.cms.contenttype.ContentTypeExtensionPoint"
          id="org.ametys.web.default.Content.article"
          class="org.ametys.cms.contenttype.DefaultContentType">

   <content-type>
       <label i18n="true">CONTENT_ARTICLE_LABEL</label>
       <description i18n="true">CONTENT_ARTICLE_DESCRIPTION</description>
       <default-title i18n="true">CONTENT_ARTICLE_DEFAULT_TITLE</default-title>
       <icons>
            <glyph>ametysicon-text70</glyph>
           <small>img/content/article/icon-small.png</small>
           <medium>img/content/article/icon-medium.png</medium>
           <large>img/content/article/icon-large.png</large>
       </icons>

       <right>Web_Right_Article_Create</right>

<!-- Déclaration des attributs ici -->

<!-- Déclaration des propriétés ici -->

<!-- Déclaration des validateurs globaux ici -->

<!-- Déclaration des vues ici -->

   </content-type>
</extention>

Les icônes ou glyphes

Vous pouvez représenter votre de type de contenu soit :

  • par 3 icônes de taille 16x16, 32x32 et 48x48 pixels 
<icons>
   <small>img/content/article/icon-small.png</small>
   <medium>img/content/article/icon-medium.png</medium>
   <large>img/content/article/icon-large.png</large>
</icons>
  • par un pictogramme (glyph)

Si vous choisissez un glyph, pensez à ajouter le fichier CSS dans lequel est défini le glyph.

<icons>
   <glyph>ametysicon-text70</glyph>
</icons>
<css>
    <file plugin="core-ui">font/ametys/AmetysIcon.css</file>
</css>

Le glyph (ou l'icône "medium" s'il n'y a pas de glyph), ainsi que le libellé et la description sont utilisées pour le menu "Ajouter un contenu"

Le glyph est également utilisé lors de l'insertion d'un contenu dans une page et dans les résultats du moteur de recherche. (Dans ces 2 cas, si le glyph n'est pas présent, c'est l'icône "small" qui est utilisé.

Les attributs

Les attributs sont des paramètres classiques comme décrits dans la page Généralités sur les paramètres avec quelques variations et éléments supplémentaires.

Depuis la version d'Ametys 4.7, deux syntaxes cohabitent :
    - la syntaxe classique, détaillée ci-dessous,
    - et la syntaxe historique, présentée dans un § à part.
Il est possible de déclarer certains attributs avec la syntaxe classique et d'autre avec la syntaxe historique.

Déclaration simple

Comme tout paramètre, un attribut possède à minima un nom unique, un libellé, une description et un type (string, date, long, ...) et se déclare comme suit dans la balise <cms:metadata>:

Exemple de déclaration d'un attribut "Titre" de type string, obligatoire

<attribute name="title" type="string">
    <label i18n="true">CONTENT_ARTICLE_TITLE</label>
    <description i18n="true">CONTENT_ARTICLE_TITLE_DESC</description>
    <validation>
        <mandatory />
    </validation>
</attribute>

Voir la liste des types disponibles pour un attribut.

Validation

L'instruction <validation> permet de définir des règles de validation sur un attribut:

  • <mandatory> pour rendre l'attribut obligatoire
  • <regexp> pour définir une expression régulière
  • <invalidText> pour personnaliser le message en cas de saisie incorrecte (expression régulière non respectée)
  • <custom-validator> classe java implémentant l'interface org.ametys.runtime.util.parameter.Validator pour définir son propre validateur
    • Par exemple org.ametys.runtime.util.parameter.TextValidator pour champ texte simple ou org.ametys.runtime.plugins.core.util.parameter.RichTextValidator pour champ riche, supportent une sous balise

  • <maxlength> pour un nombre de caractères maximum supporté

 

Exemple de validation pour un champ "adresse mail" obligatoire

<validation>
    <custom-validator class="org.ametys.runtime.plugins.core.util.parameter.TextValidator"> 
        <maxlength>60</maxlength>
        <mandatory/>
        <regexp>^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z0-9][A-Za-z0-9]+)$</regexp>
        <invalidText i18n="true">PLUGINS_WEB_REGEXP_INVALID_MAIL</invalidText>
    </custom-validator>
</validation>

Voir d'autres exemples sur la page Généralités sur les paramètres, chapitre "Validation".

Widget de modification

Il est possible de préciser un "widget" pour la modification de l'attribut. Par exemple, pour un attribut de type "string", on peut utiliser le widget "edition.textarea" pour modifier l'attribut sur plusieurs lignes.
L'utilisation d'un widget se fait au travers de la balise <widget> comme dans l'exemple ci-dessous:

Exemple d'utilisation d'un widget

<attribute name="abstract" type="string">
    <label i18n="false">CONTENT_ARTICLE_ABSTRACT</label>
    <description i18n="true">CONTENT_ARTICLE_ABSTRACT_DESC</description>
    <widget>edition.textarea</widget>
</attribute>

Voir la liste des widgets de modification disponibles pour les attributs de contenus.

Attribut composite

Un attribut peut être "composite", c'est à dire lui-même composé d'autres attributs. Par exemple, une illustration est composée d'un fichier et d'un texte alternatif.

Exemple de déclaration d'un attribut composite

<attribute name="illustration" type="composite">
    <label i18n="true">CONTENT_ARTICLE_ILLUSTRATION</label>
    <description i18n="true">CONTENT_ARTICLE_ILLUSTRATION_DESC</description>
   <attribute name="image" type="file">
        <label i18n="true">CONTENT_ARTICLE_IMAGE</label>
        <description i18n="true">CONTENT_ARTICLE_IMAGE_DESC</description>
        <widget>external-or-resource-image</widget>
   </attribute>
   <attribute name="alt-text" type="string">
        <label i18n="true">CONTENT_ARTICLE_IMAGE_ALT</label>
        <description i18n="true">CONTENT_ARTICLE_IMAGE_ALT_DESC</description>
   </attribute>
</attribute>

Il est possible de définir des attributs composites multiples, c'est à dire pouvant être répétés autant de fois que souhaité. Par exemple pour pouvoir ajouter 0 à n pièces jointes à un contenu. C'est ce qu'on appelle des "repeater".

Exemple de déclaration d'un repeater

<attribute name="attachments" type="repeater" initial-size="0">
    <label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILES</label>
    <description i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILES_DESC</description>
  <add-label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_ADD</add-label>
  <del-label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_DEL</del-label>
   <attribute name="attachment" type="file">
        <label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE</label>
        <description i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_DESC</description> 
   </attribute> 
   <attribute name="attachment-text" type="string">
        <label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_TEXT</label>
        <description i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_TEXT_DESC</description> 
   </attribute> 
</attribute>
  • add-label permet de redéfinir le tooltip du bouton d'ajout ("Ajouter une entrée" par défaut
  • del-label permet de redéfinir le tooltip du bouton de suppression ("Supprimer une entrée" par défaut)
  • header-label permet de mettre un libellé personnalisé à chaque entrée du repeater.
      La valeur est une phrase qui va référencer les valeurs des champs du repeater avec la syntaxte {field}.
      Par exemple ici: {amout} € du {date} {sent:pick("", "(envoyée)")}

      entre les {} il faut mettre l'identifiant du champ, et facultativement une fonction à lui appliquer à choisir dans Ext.util.Format 
      Voici quelques exemples :
      * {date:date("c")} où "c" est un format de date à choisir dans Ext.Date 
      * {datetime:pick("", " - ")}{datetime} pour préfixer le datetime de " - " si il est non vide
      * {linkArticle:or("[Aucun]")} pour écrire "[Aucun]" si la valeur est vide
      * {boolean:pick("Faux", "Vrai")} pour un boolean

Depuis la version 4.8 d'Ametys, il est possible d'afficher les entrées de repeater dans un tableau dans le formulaire de modification.
Attention, il n'est pas possible d'utiliser ce mode d'affichage pour des repeaters contenant des rich-texts, ou d'autres attributs composites. Dans ce cas, le mode table sera ignoré.
Aussi, nous conseillons de réserver ce mode d'affichage à des repeaters simples, composé de pas plus de 4 ou 5 attributs.

Exemple de déclaration d'un repeater en mode table

<attribute name="attachments" type="repeater" initial-size="0">
    <label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILES</label>
    <description i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILES_DESC</description>
    <add-label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_ADD</add-label>
    <del-label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_DEL</del-label>
    
    <widget-params>
       <param name="mode">table</param>
    </widget-params>
    
    <attribute name="attachment" type="file">
        <label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE</label>
      <description i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_DESC</description>
    </attribute> 
    <attribute name="attachment-text" type="string">
       <label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_TEXT</label>
       <description i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_TEXT_DESC</description>
       <widget-params>
         <param name="flex">0.5</param>
       </widget-params>
    </attribute> 
</attribute>

Toute la configuration passe par des paramètres de widget

  • Sur le repeater, ajouter le paramètre mode avec la valeur table
  • Sur les attributs qui composent le repeater, il est possible, mais non nécessaire, de régler la largeur de certains attributs
    • Soit en utilisant le paramètre width. En donnant la taille en pixel de certains attributs. Les autres attributs se répartiront la place restante de manière égale.
    • Soit en utilisant le paramètre flex. Le flex permet de donner des proportions entre les attributs. La valeur par défaut est 1.
      • Exemple : avec 2 attributs, si l'un des 2 a une valeur 0.5 et l'autre 1. La totalité est de 1.5. Le premier attribut prend 1/3 de la largeur, le second les 2/3 restants

Les énumérations

Un attribut énuméré peut prendre une valeur parmi une liste définie : une liste statique ou dynamique.

Voir les généralité sur les paramètres pour l'écriture d'une liste statique de valeurs.

Les valeurs par défaut

Il est possible définir des valeurs par défaut sur un attribut. Voir les généralités sur les paramètres.

Pour les attributs de type content qui spécifient un type de contenu cible, la valeur par défaut peut être de type "attribute" Cela permet d'aller chercher le premier contenu dont l'attribut renseigné a une valeur particulière.

L'attribut cible ne peut pas être dans un composite ou dans un repeater, et doit être du type string, long ou double. 

Exemple :

La définition ci-dessous permet de définir la valeur par défaut français pour l'attribut "Langue d'enseignement" (valeur provenant d'un table de référence).  

<attribute name="teachingLanguage" type="content" contentType="odf-enumeration.Language" multiple="true">
    <label i18n="true">PLUGINS_ODF_COURSE_TEACHINGLANG</label>
    <description i18n="true">PLUGINS_ODF_COURSE_TEACHINGLANG_DESC</description>
   <widget>edition.select-referencetable-content</widget>
   <default-value type="attribute" name="code">fr</default-value>
</attribute>

Restrictions

Il est possible de définir des restrictions en lecture et/ou écriture sur les attributs.

Les restrictions peuvent être de plusieurs sorte :

  • restriction en lecture ou lecture/écriture
  • restriction en lecture ou lecture/écriture en fonction d'un droit
  • restriction en lecture ou lecture/écriture en fonction d'un état de workflow

Restriction en lecture ou lecture/écriture

<attribute name="typology" type="string">
    <label i18n="false">Typologie</label>
    <description i18n="false">Typologie de projet</description>
   <restrict-to>
       <cannot read-write-direction="write"/>
   </restrict-to>
</attribute>

Dans cette configuration, si l'attribut read-write-direction vaut:

  • write : le contributeur peut voir l'attribut, sans pouvoir le modifier (accès en lecture seule)
  • read : le contributeur ne peut ni voir, ni modifier l'attribut

Restriction en lecture ou lecture/écriture en fonction d'un droit

<attribute name="typology" type="string">
    <label i18n="false">Typologie</label>
    <description i18n="false">Typologie de projet</description>
   <restrict-to>
       <right id="Web_Right_SuperEdit" read-write-direction="write"/>
   </restrict-to>
</attribute>

Dans cette configuration,

  • la balise <right> détermine le droit que doit posséder le contributeur
  • si l'attribut read-write-direction vaut :
    • write : le contributeur ne peut modifier l'attribut que s'il possède le droit "Web_Right_SuperEdit", sinon, il aura accès à l'attribut uniquement en lecture
    • read : le contributeur aura accès en lecture/écriture à l'attribut uniquement s'il possède le droit "Web_Right_SuperEdit"

Restriction en lecture ou lecture/écriture en fonction d'un état du workflow

<attribute name="typology" type="string">
    <label i18n="false">Typologie</label>
    <description i18n="false">Typologie de projet</description>
   <restrict-to>
       <workflow step="2" read-write-direction="write"/>
       <workflow step="3" read-write-direction="read"/>
   </restrict-to>
</attribute>

Dans cette configuration,

  • la balise <workflow> détermine l'état de workflow concerné par la restriction
  • si l'attribut read-write-direction vaut :
    • write : le contributeur ne peut modifier l'attribut que si le contenu est actuellement dans l'état de workflow défini
    • read : le contributeur aura accès à l'attribut en lecture/écriture que si le contenu est actuellement dans l'état de workflow défini

Restrictions sur les composites multiples (repeater)

Les restrictions décrites ci-dessus peuvent s'appliquer également aux repeaters

<attribute name="photos" type="repeater" initial-size="0">
    <label i18n="false">Photos</label>
    <description i18n="false">Photos</description>
   <add-label i18n="false">Ajouter une photos</add-label>
   <del-label i18n="false">Supprimer la photos</del-label>
   <restrict-to>
       <right read-write-direction="write" id="Web_Right_SuperEdit"/>
   </restrict-to>
   <attribute name="image" type="file">
        <label i18n="false">Fichier</label>
        <description i18n="false">Fichier image</description>
   </attribute>
   <attribute name="legend" type="string">
        <label i18n="false">Légende</label>
        <description i18n="false">Légende</description>
   </attribute>
</attribute>

Si un contributeur n'a pas accès en écriture à un repeater, alors il ne pourra pas ni ajouter, ni supprimer, ni déplacer les entrées du repeater

Syntaxe historique

Il est possible de faire exactement les même choses avec la syntaxe historique. Les seules différences sont les suivante :

  • On utilise le mot clé metadata plutôt que attribute
  • Sauf pour les repeaters, pour lesquels on utilise le mot clé repeater sans avoir à spécifier de type

Exemple de déclaration d'un attribut "Titre" avec la syntaxe historique

<metadata name="title" type="string">
    <label i18n="true">CONTENT_ARTICLE_TITLE</label>
    <description i18n="true">CONTENT_ARTICLE_TITLE_DESC</description>
    <validation>
        <mandatory />
    </validation>
</metadata>

Exemple de déclaration d'un repeater avec la syntaxe historique

<repeater name="attachments" initial-size="0">
  <label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILES</label>
  <description i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILES_DESC</description>
  <add-label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_ADD</add-label>
  <del-label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_DEL</del-label>
  <metadata name="attachment" type="file">
        <label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE</label>
        <description i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_DESC</description> 
  </metadata> 
  <metadata name="attachment-text" type="string">
        <label i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_TEXT</label>
        <description i18n="true">PLUGINS_ODF_PROGRAM_ATTACHED_FILE_TEXT_DESC</description> 
  </metadata> 
</metadata>

Les propriétés

Une propriété est une donnée dont la valeur est calculée à partir des données d'un contenu.

Elle peut soit faire référence à un autre élément du modèle (attribut ou propriété), soit pointer vers une classe qui va faire des calculs plus complexes

Les propriétés n'existent que depuis la version 4.6

Référencer un élément du modèle

Pour référencer un élément du modèle, la déclaration de la propriété doit indiquer le chemin de cet élément :

<property name="zipcode" path="address/zipcode" />

Une propriété peut référencer un élément du modèle sur un contenu distant. Dans l'exemple suivant, linked-content est un attribut de type content du type de contenu en cours de déclaration :

<property name="linked-title" path="linked-content/title" />
<property name="linked-creator" path="linked-content/creator" />

Pointer vers une classe

Vous pouvez également créer une propriété plus complexe en créant une classe java et en déclarant une propriété qui pointe vers cette classe. Par exemple, dans les espaces projet, les brèves ont une propriété pinned, qui détermine si la brève est étiquetée avec l'étiquette 'pin' :

<property name="pinned" class="org.ametys.plugins.workspaces.wall.PinProperty">
   <label i18n="true">plugin.workspaces:PLUGINS_WORKSPACES_WALL_CONTENT_PIN_LABEL</label>
   <description i18n="true">plugin.workspaces:PLUGINS_WORKSPACES_WALL_CONTENT_PIN_DESC</description>
</property>

Validation globale

La balise <global-validators> permet de  définir des règles de validation entre plusieurs attributs. Il est possible de définir sont propre validateur global en implémentant l'interface org.ametys.cms.contentype.ContentValidator. Des validateurs ermettant de vérifier les intervalles entre 2 attributs existent déjà dans Ametys :

  • org.ametys.cms.contenttype.validation.DateIntervalValidator pour vérifier l'intervalle entre 2 attributs de type date,
  • org.ametys.cms.contenttype.validation.DateTimeIntervalValidator pour vérifier l'intervalle entre 2 attributs de type datetime,
  • org.ametys.cms.contenttype.validation.LongIntervalValidator pour vérifier l'intervalle entre 2 attributs de type long,
  • org.ametys.cms.contenttype.validation.DoubleIntervalValidator pour vérifier l'intervalle entre 2 attributs de type double

Un type de contenu peut contenir plusieurs validateurs globaux. Ces validateurs permettent de définir des règles de validation entre plusieurs attributs. On peut par exemple vérifier que la valeur d'un attribut de type date est inférieure à la valeur d'un autre attribut de type date :

Exemple de déclaration d'un validateur global qui vérifie que la valeur de l'attribut "start" (de type datetime) est inférieure à la valeur de l'attribut "end" (de type datetime également)

<global-validators>
   <global-validator class="org.ametys.cms.contenttype.validation.DateTimeIntervalValidator">
     <startDate path="start"/>
      <endDate path="end"/>
   </global-validator>
</global-validators>

Les vues

Une vue est un ensemble d'éléments du modèle. Chaque vue fait référence aux éléments déclarés nécessaires à son affichage.

Depuis la version d'Ametys 4.4, deux syntaxes de vues cohabitent :
    - la syntaxe classique, détaillée ci-dessous,
    - et la syntaxe historique, présentée dans un § à part.
Il est possible de déclarer certaines vues avec la syntaxe classique et d'autre avec la syntaxe historique.

Pour une version d'Ametys antérieure à la 4.4, seule la syntaxe historique est disponible.

Les propriétés ne peuvent être référencées que par les vues qui utilisent la nouvelle syntaxe.

Certaines vues ont un attribut type, valué à "view" ou "edition". Depuis la version d'Ametys 4.6.0, ce type n'est plus utilisé, l'attribut peut être supprimé sans problème.

Syntaxe

Une vue est déclarée comme suit, dans la balise <view> :

Exemple de vue "main"

<view name="main">
   <group name="group1" role="tab">
      <item ref="title" />
      <item ref="document-subtitle" />
          <item ref="illustration">
          <item ref="image" />
          <item ref="alt-text" />
      </item>
      <item ref="abstract" />
      <item ref="content" />
       <label i18n="true">plugin.cms:PLUGINS_CMS_VIEW_MAIN</label>
       <description i18n="true">plugin.cms:PLUGINS_CMS_VIEW_MAIN_DESC</description>
   </group>
</view>

Exemple de vue "abstract"

<view name="abstract">
  <group name="presentation" role="tab">
      <item ref="title" />
      <item ref="document-subtitle" />
      <item ref="illustration">
          <item ref="image" />
          <item ref="alt-text" />
      </item>
      <item ref="abstract" />
      <item ref="content" />
      <label i18n="true">plugin.myplugin:PRESENTATION_GROUP_LABEL</label>
      <description i18n="true">plugin.myplugin:PRESENTATION_GROUP_DESC</description>
   </group>
   <label i18n="true">plugin.cms:PLUGINS_CMS_VIEW_ABSTRACT</label>
   <description i18n="true">plugin.cms:PLUGINS_CMS_VIEW_ABSTRACT_DESC</description>
  <icons>
     <small>img/content/article/abstract-view-icon-small.png</small>
     <medium>img/content/article/abstract-view-icon-small.png</medium>
     <large>img/content/article/abstract-view-icon-small.png</large>
     <glyph>ametysicon-newspaper1</glyph>
     <decorator>decorator-ametysicon-test</decorator>
   </icons>
</view>
  • Sur la balise view  : 
    • L'attribut name est le nom de vue (ex: main, abstract, link, details, ...) Pour plus de détails sur le nom des vues, consulter le § ci-dessous "Les vues obligatoires et optionnelles"
    • L'attribut internal, optionnel permet de "privatiser" la vue, c'est à dire la rendre invisible pour le contributeur. 
  • La balise  group permet de regrouper les différents éléments de la vue. 
    • L'attribut name correspond au nom du groupe, cet attribut est optionnel, mais il peut être nécessaire quand on veut faire de la surcharge des vues (voir le § correspondant)
    • L'attribut role définit le type de regroupement : 
      • La valeur tab représente un regroupement par onglets
      • La valeur fieldset correspond à un liseré représentant le regroupement
      • Cet attribut est optionnel : si celui-ci n'est pas défini, il prend la valeur tab par défaut pour le premier niveau de regroupement, et la valeur fieldset par défaut pour les niveaux inférieurs. 
    • La balise label définit le libellé du groupe
    • La balise description définit la description du groupe
  • Les balises item font référence à un élément du modèle décrit dans le type de contenu, en indiquant son nom. Il peut s'agir d'un attribut, d'une propriété définie par le type de contenu, ou d'une propriété système.

Pour les version 4.4 à 4.7 inclues, la syntaxe est <attribute-ref name="title" />, et non <item ref="title" />

  • la balise  label définit le libellé de la vue. S'il n'est pas renseigné, le nom de la vue sera utilisé en tant que libellé.
  • la balise description définit la description de la vue
  • la balise icons permet de définir les icones de la vue
    • les balises small, medium et large, pour définir respectivement les icônes de taille 16x16, 32x32 et 48x48 pixels 
    • la balise glyph pour le pictogramme. SI le pictogramme n'est pas renseigné, mais u'il y a une icône medium, c'est elle qui sera utilisée.
    • la balise decorator pour ajouter un décorateur au pictogramme

Inclure une vue dans une autre

Syntaxe disponible à partir de la version 4.8 d'Ametys

On peut inclure une vue dans une autre vue avec la syntaxe suivante :

<view name="vue-de-reference">
    <item ref="title"/>
    <item ref="code"/>
</view>

<view name="autre-vue">
  <include view="vue-de-reference"/>
    <item ref="shortLabel"/>
</view>

Cette référence de vue peut être incluse dans un groupe.

Vues jointées

Cette syntaxe de vue permet de réaliser des vues jointées (utiles pour les contenus liés); en voici les exemples :

Ajout de quelques attributs d'un contenu lié

Dans l'exemple ci-dessous, les attributs "att1" et "att2" du linked-content sont ajoutés à la vue

<item ref="linked-content">        
  <item ref="att1" />                
  <item ref="att2" />         
</item>

Ajout de tous les attributs d'une vue

Dans l'exemple ci-dessous, tous les attributs présents dans la vue "abstract" du linked-content sont ajoutés à la vue

<item ref="linked-content">
   <view name="abstract" />
</item>

Ajout de tous les attributs d'une vue et d'autres attributs du contenu non présents dans la vue

Dans l'exemple ci-dessous :

  • tous les attributs présents dans la vue "abstract" du linked-content sont ajoutés à la vue
  • L'attribut 'att1' (non présent dans la vue abstract) est ajouté à la vue
<item ref="linked-content">        
   <view name="abstract" />                
  <item ref="att1" />         
<item>

Ajout de tous les attributs du contenu lié

Dans l'exemple ci-dessous, tous les attributs définis dans le modèle du linked-content sont ajoutés à la vue

<item ref="linked-content">
  <item ref="*" />
</item>

Ajout de tous les attributs d'un composite (ou repeater)

Dans l'exemple ci-dessous, tous les attributs du composite "illustration" sont ajoutés à la vue. 

<item ref="illustration">
  <item ref="*" />
</item>

Syntaxe simplifiée

Syntaxe disponible à partir de la version 4.8 d'Ametys

Il est également possible de faire directement référence à un élément du modèle qui est dans un groupe, ou dans un contenu lié avec la syntaxe suivante :

<item ref="composite/linked-content/att1" /> 

On peut également faire référence à une vue :

<item ref="composite/linked-content[abstract]" />

ou ajouter tous les éléments d'un contenu lié ou d'un composite (ou repeater) :

<item ref="composite/linked-content/*" />
<item ref="illustration/*" />

Surcharge d'une vue

Dans le cadre de l'héritage, ou de la modification d'un type de contenu (voir les § correspondants ci-après), il est possible de surcharger une vue, par exemple pour y ajouter un attribut, sans redéfinir la vue complètement. Pour cela, il suffit d'ajouter l'attribut override, avec la valeur true, lors de la définition de la vue.

Modification des données générales d'une vue

Dans l'exemple ci-dessous, la "privatisation", le label, la description et les icônes de la vue sont modifiés. Ces éléments ne sont pas obligatoires. S'ils ne sont pas renseignés lors de la modification d'une vue, c'est les informations de la vue surchargée qui sont prises en compte.

<view name="abstract" override="true" internal="true">
  <label i18n="true">plugin.myplugin:MY_VIEW_ABSTACT</label>
  <description i18n="true">plugin.myplugin:MY_VIEW_ABSTACT_DESC</description>
   <icons>
     <small>img/content/article/abstract-view-other-icon-small.png</small>
     <medium>img/content/article/abstract-view-other-icon-small.png</medium>
     <large>img/content/article/abstract-view-other-icon-small.png</large>
     <glyph>ametysicon-newspaper2</glyph>
     <decorator>decorator-ametysicon-test2</decorator>
   </icons>
</view>

Ajout d'un attribut à la fin de la vue

Dans l'exemple ci-dessous, l'attribut "subject" est ajouté à la fin de la vue

<view name="abstract" override="true">
<item ref="subject" />
</view>

Ajout d'un attribut avant un autre attribut

Dans l'exemple ci-dessous, l'attribut "subject" est ajouté avant l'attribut "title". Si l'attribut "title" n'est pas présent la vue, l'attribut "subject" est ajouté à la fin de la vue.

<view name="abstract" override="true">
<item ref="subject" order-before="title" />
</view>

Ajout d'un attribut après un autre attribut

Dans l'exemple ci-dessous, l'attribut "subject" est ajouté après l'attribut "title". Si l'attribut "title" n'est pas présent la vue, l'attribut "subject" est ajouté à la fin de la vue.

<view name="abstract" override="true">
<item ref="subject" order-after="title" />
</view>

Ajout d'un attribut dans un groupe

Dans l'exemple ci-dessous, l'attribut "subject" est ajouté à la fin du groupe "presentation/general". Si le groupe "presentation/general" n'est pas présent la vue, l'attribut "subject" est ajouté à la fin de la vue. Pour surcharger une vue qui a des groupes, il est important que tous les groupes de cette vue soient correctement nommés.

<view name="abstract" override="true">
<item ref="subject" group="presentation/general" />
</view>

Ajout d'un attribut après un attribut qui se situe dans un groupe

Dans l'exemple ci-dessous, l'attribut "subject" est ajouté après l'attribut "title" qui est dans le groupe "presentation/general". Si le groupe "presentation/general" n'est pas présent la vue, l'attribut "subject" est ajouté à la racine de la vue, après l'attribut "title" s'il y a une référence à l'attribut "title" à la racine de la vue, ou à la fin de la vue. Si l'attribut "title" n'est pas présent dans le groupe "presentation/général", l'attribut "subject" est ajouté à la fin du groupe "presentation/general".

<view name="abstract" override="true">
<item ref="subject" order-after="title" group="presentation/general" />
</view>

Suppression d'un attribut

Dans l'exemple ci-dessous, l'attribut "title" qui se trouve à la racine de la vue est supprimé de la vue. Si l'attribut "title" n'est pas présent à la racine de la vue, aucun élément n'est supprimé.

<view name="abstract" override="true">
 <remove-item ref="title" />
</view>

Suppression d'un attribut dans un groupe

Dans l'exemple ci-dessous, l'attribut "title" se trouvant dans le groupe "presentation/general" est supprimé de la vue. Si l'attribut "title" n'est pas présent dans le groupe "presentation/general", aucun élément n'est supprimé.

<view name="abstract" override="true">
 <remove-item ref="presentation/general/title" />
</view>

Suppression d'un attribut dans un composite

Dans l'exemple ci-dessous, l'attribut "alt-text" dans le composite "illustration" est supprimé de la vue. Si l'attribut "illustration/alt-text" n'est pas présent dans la vue, aucun élément n'est supprimé

<view name="abstract" override="true">
 <remove-item ref="illustration/alt-text" />
</view>

Il n'est pas possible d'ajouter un attribut dans un composite ou un repeater

Les vues obligatoires et optionnelles

Vous pouvez définir autant de vues que vous souhaitez. En revanche certaines vues sont obligatoires et doivent être déclarées pour tous types de contenus :

  • la vue "main" (obligatoire) utilisée pour le rendu du contenu dans sa vue "complète"
  • la vue "default-edition" (optionnelle) utilisée pour la modification du contenu. Si cette vue n'est pas présente, c'est la vue "main" qui sera utilisée pour la modification du contenu
  • la vue "abstract" (optionnelle) utilisée pour le rendu du contenu dans sa vue "résumé" (dans une remontée de contenu par exemple)
  • la vue "link" (optionnelle)  utilisée pour le rendu du contenu dans sa vue "lien"
  • la vue "details" (obligatoire) pour définir les attributs à afficher dans l'outil "Propriétés du contenu"
  • la vue "index" (optionnelle) est utilisée par le moteur de recherche front, afin de définir les attributs saxés dans le cas des services de recherche de page (ancien moteur de recherche), ou du nouveau moteur de recherche en mode page. 

Pour être rendue, une vue est liée à un fichier XSL.  Les données XML en entrée de cet XSL correspondent aux attributs déclarés dans cette vue.

Syntaxe historique

Dans cette ancienne syntaxe, une vue est déclarée comme suit, dans la balise <metadata-set> :

Exemple de vue "main"

<metadata-set name="main">
   <fieldset role="fieldset">
       <label>group1</label>
       <metadata-ref name="title" />
       <metadata-ref name="document-subtitle" />
       <metadata-ref name="illustration">
           <metadata-ref name="image" />
           <metadata-ref name="alt-text" />
       </metadata-ref>
       <metadata-ref name="abstract" />
       <metadata-ref name="content" />
   </fieldset>
   <label i18n="true">plugin.cms:PLUGINS_CMS_VIEW_MAIN</label>
   <description i18n="true">plugin.cms:PLUGINS_CMS_VIEW_MAIN</description>
</metadata-set>
  • Sur la balise metadata-set  : 
    • L'attribut name est le nom de vue (ex: main, abstract, link, details, ...). Pour plus de détails sur le nom des vues, consulter le § ci-dessus "Les vues obligatoires et optionnelles"
    • L'attribut internal, optionnel permet de "privatiser" la vue, c'est à dire la rendre invisible pour le contributeur. 
  • La balise  fieldset définit le groupement d'attributs
    • L'attribut role définit le type de groupement : 
      • La valeur tab représente un groupement par onglets
      • La valeur fieldset correspond à un liseré représentant le groupement
      • Cet attribut est optionnel : si celui-ci n'est pas défini, il prend la valeur tab par défaut pour le premier niveau de groupement, et la valeur fieldset par défaut pour les niveaux inférieurs. 
    • La balise label définit le libellé du groupe
    • La balise description définit la description du groupe
  • Les balises metadata-ref font référence à un attribut décrit dans le type de contenu, en indiquant son nom (il n'est pas possible de référencer une propriété dans une vue avec la nouvelle syntaxe)
  • La balise  label définit le libellé de la vue
  • La balise description définit la description de la vue

Avec la syntaxe historique, il n'est pas possible de faire des vues jointées.

Les tags

Les types de contenus peuvent recevoir des tags.

Les tags permettent des traitements spécifiques en Java.

Il existe 3 tags reconnus par toute application Ametys :

  • private : un type de contenu privé est un type de contenu qui ne peut être créé et qui n'apparait pas dans les moteurs de recherche par défaut.
  • reference-table: le type de contenu est une table de référence (voir plus loin)
  • mixin : type de contenu qui est sémantiquement un rôle (voir plus loin)

La déclaration de "tags" dans le type de contenu s'écrit :

<tags>
   <tag>reference-table</tag>
   <tag>private</tag>
</tags>

Les tags peuvent être hérités du type de contenu parent avec l'attribut inherited="true"

<tags inherited="true"/>

Tags personnalisés

Vous pouvez ajouter vos propres tags.

  • Pas besoin de déclaration préalable

  • Nécessite du code java spécifique dans des outils spécifiques

Héritage multiple

Depuis Ametys v4, un type de contenu peut hériter d'un ou plusieurs types de contenus.

L'héritage permet de créer un nouveau de types de contenu :

  • à partir des attributs et des vues d’un ou plusieurs types existants
  • de compléter avec de nouveaux attributs
  • de modifier la définition d’un attribut existant
  • de compléter avec de nouvelles vues
  • de modifier les vues existantes

Par exemple, on peut imaginer un type de contenu "événement géolocalisé" qui étend le type "Actualité" pour y ajouter un attribut de type "geocode".

Une recherche sur les contenus de type "Actualités" renverra aussi bien des actualités que des événements géolocalisés.

Le fichier de définition correspondant à la définition du type "événement géolocalisé" serait :

<content-type xmlns:cms="http://www.ametys.org/schema/cms" extends="org.ametys.plugins.news.Content.news">
   <label i18n="true">plugin.myplugin:EVENT_LABEL</label>
   <description i18n="true">plugin.myplugin:EVENT_DESCRIPTION</description>
   <default-title i18n="true">plugin.myplugin:EVENT_DEFAULT_TITLE</default-title>

   <attribute name="geolocation" type="geocode">
        <label i18n="true">plugin.myplugin:EVENT_GEOLOCATION</label>
        <description i18n="true">plugin.myplugin:EVENT_GEOLOCATION_DESC</description>
   </attribute>

   <view name="main">
       <include from-supertype="org.ametys.plugins.news.Content.news" />
      <item ref="geolocation" />
   </view>
</content-type>

Pour éviter de redéfinir entièrement la vue "main", l'instruction <include from-supertype=".."> peut être utilisée pour inclure tous les attributs de la vue héritée.

Depuis la version 4.8, il est possible de référencer une autre vue que la vue courante avec <include from-supertype=".." view=".."/>.

Si vous voulez en revanche insérer le nouvel attribut dans un endroit spécifique du formulaire de modification, il sera nécessaire de redéfinir la vue.

Depuis la version 4.6, il est possible de surcharger les vues sans les redéfinir complètement. Voir § sur la surcharge des types de contenus.

Pour hériter de plusieurs types de contenus, les types de contenus hérités doivent être séparés par des virgules.

Les types de contenus spécifiques

Les rôles

Les rôles sont des types de contenus transversaux qui viennent compléter la sémantique d’un type de contenu.

Il est possible de créer un contenu à partir d'un rôle.

Par exemple :

  • Le rôle Dateable permet d’ajouter des dates à un type de contenu
  • Le rôle Localisable permet d’ajouter une adresse à un type de contenu
  • Actualité hérite de Article et ajoute le rôle Dateable
  • Evenement hérite de Actualité et ajoute le rôle Localisable

Une recherche de tous les contenus Dateable renverra aussi bien des Actualités que des Evenement .

Techniquement, un "rôle" est très proche d’un type de contenu :

  • il se déclare de la même façon en spécifiant le tag « mixin » (voir plus haut le chapitre sur les tags)
  • il s’utilise avec l’héritage de type de contenus
  • ils peuvent aussi s’ajouter dynamiquement via l'IHM

Si on reprend l'exemple des événements géolocalisés plus haut, on peut imaginer une autre manière de faire en utilisant un rôle :

  • définition du rôle "content-type.Localisable"

    <content-type xmlns:cms="http://www.ametys.org/schema/cms">
       <label i18n="true">plugin.myplugin:LOCALISABLE_LABEL</label>
       <description i18n="true">plugin.myplugin:LOCALISABLE_DESCRIPTION</description>
    
       <tags>
           <tag>mixin</tag>
       </tags>
    
       <attribute name="geolocation" type="geocode">
            <label i18n="true">plugin.myplugin:EVENT_GEOLOCATION</label>
            <description i18n="true">plugin.myplugin:EVENT_GEOLOCATION_DESC</description>
       </attribute>
    
       <view name="main">
          <item ref="geolocation" />
       </view>
    </cms:content-type>
  • définition du type "Événement géolocalisé" qui hérite du type "Actualité" et "Localisable"

    <content-type xmlns:cms="http://www.ametys.org/schema/cms" extends="org.ametys.plugins.news.Content.news,content-type.Localisable">
       <label i18n="true">plugin.myplugin:EVENT_LABEL</label>
       <description i18n="true">plugin.myplugin:EVENT_DESCRIPTION</description>
       <default-title i18n="true">plugin.myplugin:EVENT_DEFAULT_TITLE</default-title>
    
       <view name="main">
           <include from-supertype="org.ametys.plugins.news.Content.news" />
           <include from-supertype="content-type.Localisable" />
       </view>
    </cms:content-type>
    
    

     

Les tables de référence

Les tables de référence sont des types de contenus qui s’utilisent avec les outils de modification et de recherche dédiés.

Les types d'attributs autorisés sont limités à des attributs simple:  une table de référence ne peut pas contenir de composite ou de repeaters.

La modification d'un contenu de ce type table de référence se fait uniquement dans un tableau.

Une table de référence se déclare en spécifiant le tag « reference-table» (voir plus haut le chapitre sur les tags)

Si vous voulez que les valeurs des tables de référence remontent dans le moteur de recherche, vous devez ajouter une propriété vers sont titre. (voir le chapitre  ci-dessous Indexation et recherche)

Type de contenu privé

Un type de contenu privé est un type de contenu qui ne peut être créé via les outils standard (menu "Ajouter un contenu" ou lors de la création de page) et qui n'apparait pas dans les moteurs de recherche par défaut.

Les types de contenus ODF (formation, parcours, elp, ...) sont par exemples des types de contenus privés. Ils possède leur propre outils de recherche et de création. L'outil de recherche standard ne permet pas de les rechercher.

Une type privé  se déclare en spécifiant le tag « private» (voir plus haut le chapitre sur les tags)

Type de contenu abstrait

Un type de contenu peut être déclaré « abstrait » avec l’attribut abstract="true"

<content-type abstract="true">
   [...]
<content-type>

Définition d'un nouveau type de contenu

Un type de contenu peut-être défini à 2 endroits :

  • dans le répertoire WEB-INF/param/content-types
  • dans un nouveau plugin pour éventuellement mettre en place des traitements plus avancés, comme personnaliser la pipeline de rendu par exemple

Définition dans le répertoire WEB-INF/param/content-types

Dans WEB-INF/param/content-types/[nom_du_plugin] le nouveau type de contenu se définit de la manière suivante :

  • un fichier <id_du_content_type>.xml contient la déclaration du nouveau type de contenu (attributs + vues) comme décrit ci-dessus.

    Exemple de fichier <id_du_contenu>.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <content-type xmlns:cms="http://www.ametys.org/schema/cms">
       <label i18n="true">application:CONTENT_SEMINAIRE_LABEL</label>
       <description i18n="true">application:CONTENT_SEMINAIRE_DESCRIPTION</description>
       <default-title i18n="true">application:CONTENT_SEMINAIRE_DEFAULT_TITLE</default-title>
       <icons>
           <small>img/seminaire_16.png</small>
           <medium>img/seminaire_32.png</medium>
       </icons>
    
       [...]
    </content-type>
  • l'identifiant réel interne du type de contenu est "content-type.<id_du_content_type>"
  • le répertoire resources/img contient les ressources (notamment les icônes 16x16 et 32x32 pixels du type de contenu)
  • le catalogue i18n par défaut est celui de l'application (dans WEB-INF/i18n)
  • le répertoire stylesheets/content-type.<id_du_content_type> contient l'ensemble des fichiers content-type.<id_du_content_type>.xsl et content-type.<id_du_content_type>-<nom_de_la_vue>.xsl pour le rendu graphique des différentes vues

Le répertoire [nom_du_plugin] peut correspondre à n'importe quel nom de plugins existant. Il est conseillé d'utiliser "web".

Exemple d'organisation de fichiers pour la déclaration d'un nouveau type de contenu "séminaire"

Définition dans un plugin

Dans un plugin, un nouveau type de contenu est défini dans une extension dans le fichier plugin.xml :

<extension point="org.ametys.cms.contenttype.ContentTypeExtensionPoint"
          id="org.ametys.web.default.Content.article"
          class="org.ametys.cms.contenttype.DefaultContentType">

   <content-type>
        [...]
   </content-type>
</extension>

Modification d'un type de contenu existant

Il est possible de surcharger un type de contenu existant. Par exemple, pour lui ajouter des attributs et/ou des validateurs globaux ou pour surcharger des vues. Comme pour la déclaration d'un nouveau type de contenu, les modifications peuvent être définies à 2 endroits :

  • dans le répertoire WEB-INF/param/content-types/_override
  • dans un nouveau plugin pour éventuellement mettre en place des traitements plus avancés.

Modification dans le répertoire WEB-INF/param/content-types/_override

Pour surcharger un type de contenu, vous pouvez créer un fichier <id du content type>.xml dans le répertoire WEB-INF/param/content-types/_override de votre application

Exemple de surcharge des contenus "Actualité" et "Galerie multimédia"

Exemple de surcharge dans le dossier _override : ajout de l'attribut "subject", redéfinition de la vue "link" et surcharge de la vue "main"

<?xml version="1.0" encoding="UTF-8" ?>

<content-type xmlns:cms="http://www.ametys.org/schema/cms">
   <attribute name="subject" type="string">
        <label i18n="true">application:CONTENT_NEWS_SUBJECT</label>
        <description i18n="true">application:CONTENT_NEWS_SUBJECT_DESC</description>
   </attribute>

   <view name="link">
      <item ref="title" />
      <item ref="document-subtitle" />
      <item ref="start-date" />
      <item ref="end-date" /> 
      <item ref="subject" /> 
       <label i18n="true">plugin.web:PLUGINS_WEB_VIEW_ABSTRACT</label>
   </view>

  <view name="main" override="true">
     <item ref="subject" order-before="abstract" />
   </view>
</content-type>

Modification dans un plugin

Dans un plugin, les modification d'un type de contenu sont définies dans une extension dans le fichier plugin.xml. Il est possible de modifier plusieurs types de contenus à la fois.

La modification d'un type de contenu peut être conditionnelle. Par exemple, pour n'effectuer les modifications que si un paramètre de configuration est renseigné, ou si sa valeur est true (en cas de paramètre de type booléen), utilisez la classe org.ametys.cms.contenttype.ConfigBasedContentTypeOverrides. Vous pouvez également créer vos propres conditions, en créant une classe java dans votre plugin, qui implémente l'interface org.ametys.cms.contenttype.ContentTypeOverridesExtension.

La classe org.ametys.cms.contenttype.StaticContentTypeOverrides permet d'effectuer les modifications sans condition.

Exemple de surcharge dans un plugin : types Article et Actualité, sans condition

<extension point="org.ametys.cms.contenttype.ContentTypeOverridesExtensionPoint"
        id="org.ametys.web.default.Content.override.article"
    class="org.ametys.cms.contenttype.StaticContentTypeOverrides">

   <content-types>
     <content-type id="org.ametys.web.default.Content.article" />
     <content-type id="org.ametys.plugins.news.Content.news" />
   </content-types>

 [...]

</extension>

Exemple de surcharge dans un plugin : type Article seulement si le paramètre de configuration "runtime.ametys.public" est à true

<extension point="org.ametys.cms.contenttype.ContentTypeOverridesExtensionPoint"
        id="org.ametys.web.default.Content.override.article"
      class="org.ametys.cms.contenttype.ConfigBasedContentTypeOverrides">

   <content-types>
     <content-type id="org.ametys.web.default.Content.article" />
   </content-types>
  <config-param>runtime.ametys.public</config-param>

 [...]
</extension>

Ordre de prise en compte des surcharges

Il y a donc plusieurs endroits pour créer ou modifier un type de contenu et ses éléments. Voici dans l'ordre dans lequel seront pris en compte les différentes déclarations des élements :

  1. On regarde d'abord les éléments définis par les parents du type de contenu (en effectuant le même algo que celui cité ici)
  2. Ensuite on regarde les éléments définis ou modifiés dans la déclaration initiale du type
  3. Puis on regarde les modifications apportées par les surcharges dans les extensions. Attention, les surcharges dans les extensions sont faite dans un ordre aléatoire. On ne sait pas à l'avance si une extension donnée sera prise en compte avant telle ou telle autre extension.
  4. Et finalement dans le répertoire WEB-INF/param/content-types

La surcharge des vues est plus complexe, car dans chacun des cas si dessus, il est possible de redéfinir complètement une vue, ou de seulement en surcharger quelques éléments. On commence par trouve à quel niveau (déclaration initiale, surcharge par extension ou répertoire WEB-INF/param/content-types) se trouve la dernière (re)définition complète de la vue. Puis on cherche les surcharges dans les niveaux équivalents ou en dessous.

Exemples de déclarations de types de contenus

Les exemples ci-dessous permettent d'avoir une vue d'ensemble de la syntaxe de déclaration d'un type de contenu. On détaille également le fonctionnement de l'algorithme de modification des éléments d'un type de contenu

Exemple complet de déclaration d'un type contenu simple

Voici ci-dessous l'exemple complet de déclaration d'un nouveau de type de contenu, une partie du type Actualité :

<?xml version="1.0" encoding="UTF-8" ?>

<extension xmlns:cms="http://www.ametys.org/schema/cms"
           class="org.ametys.cms.contenttype.DefaultContentType">
  <content-type>

        <label i18n="true">CONTENT_NEWS_LABEL</label>
        <description i18n="true">CONTENT_NEWS_DESCRIPTION</description>
        <default-title i18n="true">CONTENT_NEWS_DEFAULT_TITLE</default-title>

       <!-- Les icônes -->        
       <icons>
            <glyph>ametysicon-newspaper1</glyph>
            <small>img/news_16.png</small>
            <medium>img/news_32.png</medium>
            <large>img/news_48.png</large>
        </icons>
        <css>
            <file plugin="core-ui">font/ametys/AmetysIcon.css</file>
      </css>
        
       <!-- Liste des attributs -->
        <attribute name="title" type="string">
            <label i18n="true">CONTENT_NEWS_TITLE</label>
            <description i18n="true">CONTENT_NEWS_TITLE_DESC</description>
            <validation>
                <mandatory />
            </validation>
        </attribute>
        
        <attribute name="document-subtitle" type="string">
            <label i18n="true">CONTENT_NEWS_SUBTITLE</label>
            <description i18n="true">CONTENT_NEWS_SUBTITLE_DESC</description>
      </attribute>
    
        <attribute name="illustration" type="composite">
            <label i18n="true">CONTENT_NEWS_ILLUSTRATION</label>
            <description i18n="true">CONTENT_NEWS_ILLUSTRATION_DESC</description>
            <attribute name="image" type="file">
                <label i18n="true">CONTENT_NEWS_IMAGE</label>
                <description i18n="true">CONTENT_NEWS_IMAGE_DESC</description>
                <widget>edition.file</widget>
                <widget-params>
                    <param name="allowSources">external,resource</param>
                    <param name="filter">image</param>
                </widget-params>
            </attribute>
            <attribute name="alt-text" type="string">
                <label i18n="true">CONTENT_NEWS_IMAGE_ALT</label>
                <description i18n="true">CONTENT_NEWS_IMAGE_ALT_DESC</description>
            </attribute>
        </attribute>
    
        <attribute name="start-date" type="datetime">
            <label i18n="true">CONTENT_NEWS_START_DATE</label>
            <description i18n="true">CONTENT_NEWS_START_DATE_DESC</description>
            <validation>
                <invalidText i18n="true">CONTENT_NEWS_DATE_INVALID_FORMAT</invalidText>
            </validation>
        </attribute>
        <attribute name="end-date" type="datetime">
            <label i18n="true">CONTENT_NEWS_END_DATE</label>
            <description i18n="true">CONTENT_NEWS_END_DATE_DESC</description>
            <validation>
                <invalidText i18n="true">CONTENT_NEWS_DATE_INVALID_FORMAT</invalidText>
            </validation>
        </attribute>
    
        <attribute name="content" type="rich-text">
            <label i18n="true">CONTENT_NEWS_CONTENT</label>
            <description i18n="true">plugin.news:CONTENT_NEWS_CONTENT_DESC</description>
            <validation>
                <mandatory />
            </validation>
      </attribute>

       <!-- Validation globale -->
        <global-validators>
            <global-validator class="org.ametys.cms.contenttype.validation.DateTimeIntervalValidator">
                <startDate path="start-date"/>
                <endDate path="end-date"/>
            </global-validator>
        </global-validators>
    
       <!-- Vue principale -->
        <view name="main">
          <item ref="title" />
          <item ref="document-subtitle" />
          <item ref="start-date" />
          <item ref="end-date" />
          <item ref="illustration/*" />
        <item ref="content" />
            <label i18n="true">plugin.cms:PLUGINS_CMS_VIEW_MAIN</label>
            <description i18n="true">plugin.cms:PLUGINS_CMS_VIEW_MAIN_DESC</description>
        </view>
    
      <!-- Autres vues -->
        <view name="abstract">
          <item ref="title" />
          <item ref="start-date" />
          <item ref="end-date" />
          <item ref="illustration/*" />
            <label i18n="true">plugin.cms:PLUGINS_CMS_VIEW_ABSTRACT</label>
            <description i18n="true">plugin.cms:PLUGINS_CMS_VIEW_ABSTRACT_DESC</description>
        </view>
      
        <view name="link">
          <item ref="title" />
          <item ref="document-subtitle" />
          <item ref="start-date" />
          <item ref="end-date" />
            <label i18n="true">plugin.cms:PLUGINS_CMS_VIEW_LINK</label>
            <description i18n="true">plugin.cms:PLUGINS_CMS_VIEW_LINK_DESC</description>
        </view>
  
        <view name="details" internal="true">
          <item ref="title" />
          <item ref="document-subtitle" />
          <item ref="start-date" />
          <item ref="end-date" />
            <dublin-core/>
        </view>
    </content-type>
</extension>

Exemples de modifications du type de contenu simple

Ajout d'un attribut abstract et surcharge des vues main et abstract :

<extension point="org.ametys.cms.contenttype.ContentTypeOverridesExtensionPoint"
          id="org.ametys.web.default.Content.override.article"
          class="org.ametys.cms.contenttype.StaticContentTypeOverrides">

    <content-types>
       <content-type id="org.ametys.plugins.news.Content.news" />
    </content-types>

    <attribute name="abstract" type="string">
       <label i18n="true">CONTENT_NEWS_ABSTRACT</label>
       <description i18n="true">CONTENT_NEWS_ABSTRACT_DESC</description>
       <widget>edition.textarea</widget>
    </attribute>

    <view name="main" override="true">
     <item ref="abstract" order-after="document-subtitle" />
    </view>
  
    <view name="abstract" override="true">
     <item ref="abstract" order-after="title" />
    </view>

</extension>

Ajout d'un attribut comment et surcharge de la vue main :

<extension point="org.ametys.cms.contenttype.ContentTypeOverridesExtensionPoint"
          id="org.ametys.web.default.Content.override.article"
          class="org.ametys.cms.contenttype.StaticContentTypeOverrides">

    <content-types>
       <content-type id="org.ametys.plugins.news.Content.news" />
    </content-types>

  <attribute name="comment" type="boolean">
       <label i18n="true">CONTENT_NEWS_COMMENT</label>
       <description i18n="true">CONTENT_NEWS_COMMENT_DESC</description>
    </attribute>

    <view name="main" override="true">
    <item ref="abstract" order-after="document-subtitle" />
  </view>

</extension>

Les 2 extensions seront chargées dans un ordre aléatoire, l'ordre des attributs dans la vue peut donc changer. Par exemple dans la vue main de l'exemple ci-dessus, les 2 attributs ajoutés sont ajoutés après le même attribut "document-subtitle". La première extension chargée mettra son attribut après "document-subtitle", la seconde extension entre "document-subtitle" et l'attribut ajouté par la première extension.

Redéfinition de la vue abstract dans le dossier _override :

<?xml version="1.0" encoding="UTF-8" ?>

<content-type xmlns:cms="http://www.ametys.org/schema/cms">
     <view name="abstract">
       <item ref="title" />
       <item ref="comment" />
         <label i18n="true">plugin.cms:PLUGINS_CMS_VIEW_ABSTRACT</label>
         <description i18n="true">plugin.cms:PLUGINS_CMS_VIEW_ABSTRACT_DESC</description>
     </view>
</content-type>

On redéfinie la vue abstract dans le dossier _override, soit au dernier niveau de modification, c'est cette redéfinition qui gagne. La vue abstract ne contiendra donc que les attributs "title" et "abstract".

Indexation et recherche

Tous les éléments du modèle (attributs et propriétés), ainsi que toutes les propriétés système sont indexés dans Solr. Ils sont donc utilisables comme colonne dans la recherche.

Propriété système fulltext

Cette propriété contient toutes les données teste d'un contenu. Elle contient donc toutes les données convertibles au format texte, à l'exception des données de type content.

Pour ajouter le titre de contenus liés au fulltext d'un contenu courant, on peut ajouter une propriété dans le type de contenu pour pointer vers le titre du contenu lié.

Exemple :

<property name="linked-title" path="linked-content/title" />

La propriété étant elle-même de type string, elle sera intégrée au fulltext

Les facettes

Pour pouvoir être utilisé en tant que facette dans une recherche, un élément du modèle (attribut ou propriété) doit soit être de type boolean, user ou content, soit avoir un énumérateur.

Le rendu graphique

Le rendu graphique d'un type de contenu est traité dans la partie Intégration graphique.

Retour en haut