CONTENIDO bietet mit dem CEC die Möglichkeit, um in bestimmte Prozesse einzugreifen und den eigenen Code auszuführen. Die Funktionsweise des CEC ist im Installations-Package unter docs/techref/plugins/contenido Extension Chainer.pdf beschrieben.

Verfügbare Chains für CONTENIDO sind der Chain-Konfigurationsdatei contenido/includes/config.chains.php definiert. Jede Chain hat normalerweise einen eindeutigen Namen, aus der man ableiten kann, wo es eingesetzt wird.
Beispiel:

/* Chain Contenido.Content.SaveContentEntry
 * This chain is called everytime when content is saved
 *
 * Parameters & order:
 * int      idartlang      idartlang (Article ID)
 * string   type           type (e.g. CMS_HTML)
 * int      typeid         typeid (e.g. CMS_HTML[1])
 * string   value          value for that type
 *
 * Returns:
 * string    The processed value
 */
$_cecRegistry->registerChain("Contenido.Content.SaveContentEntry", "int", "int", "int", "string");

Die Chain "Contenido.Content.SaveContentEntry" wird also im CONTENIDO Backend ausgeführt, wenn ein Content Inhalt (CMS_HTML, CMS_IMG, usw.) gespeichert wird. Die an die Chainfunktionen übergebenen Parameter und die Rückgabe der Funktionen sind beschrieben. In diesem Fall sollte eine eigene hinzugefüge Chainfunktion 4 Parameter annehmen und den letzten zurückliefern.

Such man in den Sourcen nach der Chain "Contenido.Content.SaveContentEntry", wird man in der Datei contenido/includes/functions.con.php fündig - genauer in der Funktion conSaveContentEntry(), darin wird die Chain abgearbeitet.

Da fällt mir z. B. folgende Einsatzmöglichkeit ein. Das Inlinediting von CONTENIDO ist zwar eine wunderbare Sache, generiert aber unter IE leider HTML-Code, der nicht valide ist. Das könnte man doch sehr gut mit Tidy wieder geradebiegen, Voraussetzung ist natürlich, dass Tidy HTML als PHP-Modul verfügbar und geladen ist.

Erstellen wir dazu z. B. ein Plugin, legen also einen Ordner tidy_html in contenido/plugins/ sowie unter tidy_html noch einen Ordner includes an.

/contenido
    /plugins
        /tidy_html
            /includes

Im Ordner includes erstellen wir eine Datei config.plugin.php, diese Datei wird eingebunden und initialisiert somit das "tidy_html" Plugin. Darin erstellen wir unsere Funktion, um Inhalte von CMS_HTML mit Tidy zu bereinigen.

/**
 * Userdefined function, which will be added to Chain "Contenido.Content.SaveContentEntry", 
 * processes contents of CONTENIDO CMS_HTML types.
 *
 * @param   int     $idartlang  idartlang (con_art_lang.idartlang)
 * @param   string  $type       CMS Typ (con_type.type)
 * @param   int     $typeid     Position of CMS-Type, e. g. 5 for CMS_HTML[5]
 * @param   string  $value      The value (HTML-Code)
 * @return  string  Processed value
 */
function myCmsHtmlCleanup($idartlang, $type, $typeid, $value) {
    if ($type !== 'CMS_HTML') {
        // type is not CMS_HTML, return value
        return $value;
    } elseif (trim($value) == '') {
        // empty value should not cleaned by tidy, return value
        return $value;
    }

    // some tidy options, like indentation and xhtml output
    $options = array('indent'=>true, 'output-xhtml'=>true);
    
    // do cleanup using tidy
    $value = tidy_parse_string($value, $options);
    tidy_clean_repair($value);

    // result is a full XHTML page, but we need only the content extract it...
    if (preg_match('~<body(.*)>(.*)<\/body>~Uis', $value, $match)) {
        $value = preg_replace(array('~(<body(.*)>)~Uis', '~(<\/body>)~Uis'), '', $match[0]);
        $value = trim($value);
    }
    
    // decorate value with comments to see the result
    return "\n<!-- tidy -->\n" . $value . "\n<!-- /tidy -->\n";
}

Die Funktion ist erstellt, nun müssen wird noch die Funktion der Chain "Contenido.Content.SaveContentEntry" hinzufügen. Das geht mit folgenden Zeilen in der config.plugin.php:

// get cec registry instance
$_cecRegistry = cApiCECRegistry::getInstance();

// add a function to CONTENIDO Extension Chainer
$_cecRegistry->addChainFunction('Contenido.Content.SaveContentEntry', 'myCmsHtmlCleanup');

Somit wurde unsere Funktion der Chain hinzugefügt und kann seine Arbeit aufnehmen. Die Funktion muss bevor es der Chain hinzugefügt wird, vorher definiert werden. Sonst wird eine Warnung ausgegeben und es passiert nichts weiter. Normalerweise ist die Datei "config.plugin.php" dafür gedacht, um ein Plugin zu initialisieren, also die Konfiguration zu setzen und benötigte Sourcen einzubinden. Zusätzliche Funktionen gehören eigentlich in eine separate Datei, die am Anfang der Pluginkonfiguration eingebunden werden kann. In diesem Beispiel ist alles der Einfachhalthalber in der Pluginkonfiguration enthalten.

Zu guter letzt sollte das nun getestet werden, dafür am besten einen Artikel im inline Editingmodus bearbeiten und speichern. Das Ergebnis im Frontend sollte ein XHML-Valider sauberer Code sein.

Die war nur ein Beispiel darüber, wie einfach eine CONTENIDO-Installation über CONTENIDO Extension Chainer um eigene Features erweitert werden kann.