déc 16

Voici un billet un peu plus pratique utilisant le framework Play!.
Contrairement à mon billet précédent, celui-ci s’adresse avant tout aux développeurs.

L’objectif est d’intégrer dans une page un éditeur de texte riche au format Textile. Cette syntaxe est très simple à appréhender et la génération de code HTML à partir de code Textile est native dans Play! grâce à la librairie Wikitext.

En ce qui concerne l’éditeur en tant que tel, nous allons utiliser l’excellent MarkItUp. Il est basé sur jQuery, lui même nativement embarqué par Play!. MarkItUp propose un éditeur modulaire, permettant de gérer plusieurs syntaxes. L’ajout de syntaxes se fait par des sets.


MarkItUp

Commençons par télécharger MarkItUp! pack sur la page des téléchargements.
Il faut aussi prendre le Basic Textile Set.
L’archive MarkItUp contient un répertoire markitup : c’est celui-ci qu’il faut décompresser dans le répertoire public de votre application Play!.
Il faut ensuite décompresser l’archive contenant le Basic Textile Set dans le répertoire public/markitup/sets : un nouveau répertoire textile a dû apparaître.

L’installation des fichiers de MarkItUp est désormais terminée. Nous reviendrons plus tard pour la configuration et la customisation de l’éditeur.

Générateur Wikitext

Nous allons avoir besoin de 2 méthodes :

  • une 1ère méthode pour générer le code destiné à l’iframe Preview. Qui dit iframe dit qu’il va falloir rajouter les feuilles css au code HTML généré.
  • une 2ième méthode destinée à générer le code qui sera faire le rendu du code Textile saisi par l’utilisateur. Cette fois-ci, il ne faut pas que les css soient inclues dans le code html généré.

J’ai décidé de créer ces 2 méthodes dans un Controler :

package controllers;

import java.io.StringWriter;

import jj.play.org.eclipse.mylyn.wikitext.core.parser.MarkupParser;
import jj.play.org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder;
import jj.play.org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder.Stylesheet;
import jj.play.org.eclipse.mylyn.wikitext.textile.core.TextileLanguage;
import play.mvc.Controller;

public class Wikitext extends Controller {

    // Controller classique Play! qui sera appelé par l'iframe Preview de MarkItUp.
    public static void renderPreview(String wiki) {
        StringWriter writer = new StringWriter();
        HtmlDocumentBuilder builder = new HtmlDocumentBuilder(writer);

        // Ajout de mes 2 css.
        Stylesheet css = new Stylesheet("/public/stylesheets/main.css");
        builder.addCssStylesheet(css);
        css = new Stylesheet("/public/stylesheets/wiki.css");
        builder.addCssStylesheet(css);

        // Création du parser Textile
        MarkupParser parser = new MarkupParser(new TextileLanguage());
        parser.setBuilder(builder);
        parser.parse(wiki);

        String htmlContent = writer.toString();
        renderText(htmlContent);
    }

    // Méthode qui sera appelée par les templates Groovy de Play!.
    public static String render(String wiki) {
        StringWriter writer = new StringWriter();
        HtmlDocumentBuilder builder = new HtmlDocumentBuilder(writer);
        // Empêche la génération des balises html et body.
        builder.setEmitAsDocument(false);

        // Création du parser Textile
        MarkupParser parser = new MarkupParser(new TextileLanguage());
        parser.setBuilder(builder);
        parser.parse(wiki);

        return writer.toString();
    }
}

Ces 2 méthodes n’ont rien de spécial : elles utilisent Wikitext qui parse le code Textile de l’utilisateur et en fait un rendu HTML.
Notez dans l’une l’ajout de mes 2 css alors que l’autre méthode ne génère pas les tags html et body.

Afin de rendre ce controller un peu plus sexy, ajoutons lui une route pour le rendu de Preview :

 
*       /wikitext/renderPreview                 Wikitext.renderPreview
 

Installation de markItUp dans nos templates

Tout d’abord, il faut ajouter dans la page que vous voulez enrichier de notre éditeur riche le code suivant qui chargera markItUp :

<!--  Loading Markitup -->
<link rel="stylesheet" type="text/css" href="@{'/public/markitup/skins/markitup/style.css'}" />
<script type="text/javascript" src="@{'/public/markitup/jquery.markitup.js'}"></script>

<link rel="stylesheet" type="text/css" href="@{'/public/markitup/sets/textile/style.css'}" />
<script type="text/javascript" src="@{'/public/markitup/sets/textile/set.js'}"></script>

<script language="javascript">
$(document).ready(function()    {
    $('#wiki').markItUp(mySettings);
});
</script>
<!-- End markitup -->

Attention à modifier le code ci-dessus pour que l’identifiant ‘#wiki’ pointe bien vers l’id du textarea que vous voulez enrichir avec markItUp.
De plus, notez la variable mySettings. Celle-ci contient la configuration du plugin markItUp sous format JSON.

Voici un exemple de textarea qui va être enrichi par le plugin markItUp :

<textarea id="wiki" name="description" cols="70" rows="20">
    Bla Bla ...
</textarea>

Configuration et customisation de markItUp

Il va falloir maintenant configurer et customiser markItUp.

Pour cela, il va falloir commencer par éditer le fichier public/markitup/sets/textile/set.js :

mySettings = {
	previewParserPath:	'/wikitext/renderPreview', // path to your Wiki parser
	previewParserVar:	'wiki',
	onShiftEnter:		{keepDefault:false, replaceWith:'\n\n'},
	markupSet: [
		{name:'Heading 1', key:'1', openWith:'h1(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
		{name:'Heading 2', key:'2', openWith:'h2(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
		{name:'Heading 3', key:'3', openWith:'h3(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
		{name:'Heading 4', key:'4', openWith:'h4(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
		{name:'Heading 5', key:'5', openWith:'h5(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
		{name:'Heading 6', key:'6', openWith:'h6(!(([![Class]!]))!). ', placeHolder:'Your title here...' },
		{name:'Paragraph', key:'P', openWith:'p(!(([![Class]!]))!). '},
		{separator:'---------------' },
		{name:'Bold', key:'B', closeWith:'*', openWith:'*'},
		{name:'Italic', key:'I', closeWith:'_', openWith:'_'},
		{name:'Stroke through', key:'S', closeWith:'-', openWith:'-'},
		{separator:'---------------' },
		{name:'Bulleted list', openWith:'(!(* |!|*)!)'},
		{name:'Numeric list', openWith:'(!(# |!|#)!)'}, 
		{separator:'---------------' },
		{name:'Picture', replaceWith:'![![Source:!:http://]!]([![Alternative text]!])!'}, 
		{name:'Link', openWith:'"', closeWith:'([![Title]!])":[![Link:!:http://]!]', placeHolder:'Your text to link here...' },
		{separator:'---------------' },
		{name:'Quotes', openWith:'bq(!(([![Class]!]))!). '},
		{name:'Code', openWith:'@', closeWith:'@'},
		{separator:'---------------' },
		{name:'Preview', call:'preview', className:'preview'}
	]
}

J’ai fais les modifications suivantes :

  • Remplissage de la variable previewParserPath : on pointe vers le controller que nous avons écrit plus tôt.
  • Ajout de la variable previewParserVar pour donner le nom du paramètre HTTP contenant le code à envoyer au controller.

Le reste du fichier sert à configurer l’apparence et les boutons de markItUp. Je vous laisse le soin de fouiller la documentation de ce plugin si vous le souhaitez.

Il ne reste qu’à terminer par un peu de customisation via une CSS.
J’ai modifié le fichier public/markitup/sets/textile/style.css et j’ai rajouté les lignes suivantes :

.markItUp  {
    width:500px;
}

.markItUpEditor {
    width:443px;
    height:220px;
}

Ces surcharges me servent uniquement à redimensionner markItUp.

Et voilà !
En une petite dizaine de minutes, nous avons réussi à transformer un simple Textarea en un éditeur riche supportant Textile avec un rendu aux petits oignons. Soignez votre CSS de rendu et vous êtes le roi du pétrole !

Bonus : Voici un projet Play! contenant le code de cet article. Lancez-le avec un play run et ça marche !
Télécharger le code.

2 Responses to “Play! Framework : enrichir votre application avec un éditeur riche Textile”

  1. [...] Ce billet était mentionné sur Twitter par nicogiard, Jean-Philippe Briend. Jean-Philippe Briend a dit: Play! : enrichir votre application avec un éditeur Textile (markItUp) : http://bit.ly/hlFzvH #playframework [...]

  2. Salut Jean-Philippe, j’ai utilisé le code de ton billet pour mettre en place un éditeur textile, et çà marche bien, merci :-)

    Par contre, lorsque j’ai voulu afficher le texte via le template engine de Play!, évidemment, le code en textile est apparu.

    J’ai donc étendu ton code pour en faire une extension java de Play!:

    http://myuri.me/3r3s

    Cela me permet d’utilise dans le template engine quelque chose comme:

    ${mavariable.textile().raw()}

    Pour afficher le code textile pré-formaté en HTML correctement.

    J’espère que cela pourra servir à quelqu’un :-)

Leave a Reply


Creative Commons License
Blog Infin-It par Infin-It est mis à disposition selon les termes de la licence Creative Commons Paternité-Pas d'Utilisation Commerciale 2.0 France.