Dans Alfastrakhovanie, nous utilisons activement le "Wiki", dont le moteur est Atlassian Confluence. La première fois que je l'ai rencontré sérieusement (dans une tentative de créer du contenu), je manquais de «dynamisme» - je voulais pouvoir former par programmation des parties de pages, interagir avec d'autres systèmes, etc.
Pendant un certain temps, il s'est cogné la tête contre différents murs, mais il a ensuite vu qu '«il n'y avait pas un mur dans la maison». Je veux partager mon expérience - comment ajouter des haut-parleurs à Confluence. J'espère que cela sera utile à ceux qui l'utilisent. Et, comme d'habitude, à tout le monde curieux.
Wiki dynamique
Initialement, Confluence propose une façon universelle d'étendre ses fonctionnalités: les plugins. Probablement, il est bon, il n'y a qu'un seul inconvénient - un seuil d'entrée élevé (vous devez apprendre beaucoup).
Après une courte réflexion (selon les normes spatiales), il y avait deux façons plus simples d'étendre ses fonctionnalités: la macro standard "HTML" et "HTML Include", dans cet article, je me concentrerai sur ce dernier plus en détail.
Il existe un principe de fonctionnement pour ces méthodes: le code HTML est intégré à la page Confluence, il peut être statique (ce qui peut également être intéressant, par exemple, pour un formatage de page non standard), et peut être dynamique (y compris les composants du serveur).
Exemple: demande de rapprochement
Examinons la façon proposée d'étendre les capacités de Confluence avec un exemple simple - une liste d'approbation de documents.
Ce que nous voulons faire: ajouter une liste d'approbation à la page afin que tout le monde puisse voir qui devrait être d'accord sur le document, s'il a été accepté et, si oui, quand.
Pour plus de commodité, nous ferons de l'élément de liste un bouton et y inscrirons le nom du coordinateur. Le bouton sera actif si la page est consultée par le coordinateur, et pas actif dans tous les autres cas.
Après approbation, le bouton "cessera d'être un bouton" - au lieu du bouton après approbation, nous tracerons sur la page le fait de l'approbation sous forme de texte (le nom de l'approbateur et la date d'approbation). Dans la version la plus brouillon (sans design), cela peut ressembler à ceci:

Schéma d'interaction

Commentaires - comment cela fonctionne:
- la page dans Confluence contient plusieurs macros "html include" - en fait des requêtes HTTP GET avec des paramètres (nous examinerons plus en détail ci-dessous)
- lors du rendu d'une page, ces requêtes (scripts python) sont exécutées sur le serveur d'application, le résultat (HTML généré) est dessiné sur la page
- au cours de son travail, le script, par exemple, contacte la base de données avec l'historique de la signature de page, si la page n'a pas encore été "signée" par le signataire - HTML contiendra un bouton (tout comme décrit ci-dessus)
- lorsque vous cliquez sur le bouton, la soumission se produit - un autre script python est appelé (un script pour traiter le fait de la coordination)
- ce script enregistre des informations sur le fait de se connecter à la base de données et redirige l'utilisateur vers la page d'origine (lors du rendu dont le fait de la signature sera pris en compte - en cliquant sur le bouton "signer")
Un peu compliqué en mots, essayons de clarifier le code.
Nous devons donc créer deux scripts
- le script pour la formation du bouton "signe" (je l'appellerai le bouton "bouton")
- un script pour déterminer le fait de signer (réaction à un clic sur un bouton - j'appellerai son script "gestionnaire")
Créons-les, commençons par le bouton.
Bouton de script
Schématiquement, comment fonctionne le script de bouton:
date = getSignDate() if date:
Le script doit être un document HTML valide, dont le corps sous la forme la plus minimale est un formulaire
- l'action du formulaire contient l'URL du script "handler"
- le bouton actif est soumettre
- les champs de formulaire masqués contiennent des paramètres supplémentaires pour le gestionnaire (dans notre cas, le nom de la page et la connexion du signataire)
Une vue approximative du script (par souci de concision, j'ai jeté tout ce qui n'était pas nécessaire - voir le code de travail complet sur github )
form = cgi.FieldStorage() signee = form["signee"].value
Script "gestionnaire"
La tâche du gestionnaire est très simple - corriger le fait d'appuyer sur le bouton "Accepter". Redirigez ensuite vers la page d'où provient la demande - lors du rendu de la page, le fait de la coordination sera déjà pris en compte (voir la description ci-dessus).
Un exemple (abrégé) de script "handler" (la version complète - voir github)
form = cgi.FieldStorage() signee = form["signee"].value
Page dans Confluence
La page de Confluence contient trois macro HTML include avec différents paramètres (voir le code ci-dessous) et dans la version la plus simple ressemble à ceci:

Code de page au format de balisage wiki - ici vous pouvez voir les paramètres
<h1> </h1> <p> , </p> <h1> </h1> <ul> <li> <ac:structured-macro ac:macro-id="..." ac:name="html-include" ac:schema-version="1"> <ac:parameter ac:name="url"> <ri:url ri:value="http://z14-0510-wiksap.vesta.ru/misc/sign_btn.py?signee=boss&actual=korolevmv&id=wikitools_sign"/> </ac:parameter> </ac:structured-macro> </li> <li> <ac:structured-macro ac:macro-id="..." ac:name="html-include" ac:schema-version="1"> <ac:parameter ac:name="url"> <ri:url ri:value="http://z14-0510-wiksap.vesta.ru/misc/sign_btn.py?signee=korolevmv&actual=korolevmv&id=wikitools_sign"/> </ac:parameter> </ac:structured-macro> </li> <li> <ac:structured-macro ac:macro-id="..." ac:name="html-include" ac:schema-version="1"> <ac:parameter ac:name="url"> <ri:url ri:value="http://z14-0510-wiksap.vesta.ru/misc/sign_btn.py?signee=maxvar&actual=korolevmv&id=wikitools_sign"/> </ac:parameter> </ac:structured-macro> </li> </ul>
Un peu de mise en place
Pour que le schéma décrit fonctionne, il est nécessaire de prendre en compte les éléments suivants:
Disponibilité de la macro HTML Include
Parfois, les administrateurs le «cachent» - il y a beaucoup de problèmes supplémentaires (de l'autre côté des possibilités).
Cette macro est gratuite et fait partie de Confluence - si vous n'en avez pas, contactez les administrateurs, laissez-les regarder ...
Listes blanches Confluence
Confluence n'exécutera pas de scripts hébergés sur des sources inconnues, l'hôte sur lequel le script est hébergé doit figurer dans les soi-disant «listes blanches» (contactez les administrateurs). Cela ne s'applique qu'au script "bouton" - le script du gestionnaire est déjà appelé par le bouton, les restrictions de Confluence ne s'appliquent pas à lui.
Exécution de script
Les scripts (boutons et gestionnaire) doivent être exécutables - copiez l'URL dans le navigateur, cela devrait fonctionner et générer du HTML, si cela ne s'est pas produit, déboguez-le.
Erreurs de script
Si l'un des scripts se bloque avec une erreur - vous ne verrez rien de bon, déboguez correctement avant de publier sur Confluence.
Options de script
Un esprit curieux pourrait prêter attention aux paramètres du script - d'une part, ils sont redondants (par exemple, le nom de la page sur laquelle le bouton d'approbation est placé - est-il connu, pourquoi le remplir?). D'un autre côté, ils ne sont pas sûrs («l'attaquant» dans notre exemple peut changer le nom de l'approbateur en sien ou supprimer le bouton de réconciliation).
La redondance peut être "surmontée" par les macros utilisateur (je me demande depuis longtemps - comment peuvent-elles être utiles dans la pratique? J'écrirai brièvement dans un article séparé). La sécurité dans Confluence est assurée par l'historique des pages - tous les "mouvements" sont enregistrés, vous pouvez tout changer, dans Confluence il reste une merveilleuse "piste d'audit" qui vous permet de comprendre en détail qui a changé quoi et quand.
Interaction avec la page
Dans notre pratique, il y a eu des cas où nous avons dû analyser le code de la page pour collecter des données (par exemple, c'est ainsi que nous avons géré le portefeuille de projets). C'est possible et même pas trop difficile. Evolutionnellement, nous sommes arrivés à la conclusion que si certaines informations sur une page sont nécessaires uniquement pour le code qui interprète ces informations, alors ces informations sont plus faciles à formuler immédiatement dans le code lui-même (sous la forme de JSON, par exemple): la modifier en mode d'édition de page est assez simple , il est tiré par le programme, mais les économies sur l'analyse et la fiabilité accrue sont importantes.
Plus d'exemples
Sinon, pourquoi avons-nous utilisé ces macros (comme idées - soudain, quelque chose se révèle utile), très brièvement
Conception de la page : si vous souhaitez concevoir la page d'une manière non standard - balisage à l'aide de CSS, qui est contenu dans le bloc HTML
Calendrier de vacances : nous utilisons un calendrier JS simple, le remplissons avec des données de JSON, que nous éditons directement dans le code de la page, nous obtenons une belle assiette avec des vacances ventilées (année, mois, semaine).
Impression de cartes de tâches pour une carte Scrum : nous définissons les paramètres (numéros de tâches dans Jira et attributs supplémentaires) sous la forme directement sur la page wiki (dans le bloc HTML), le côté serveur forme les cartes sous une forme appropriée pour l'envoi à une imprimante.
Gestion de portefeuille de projets : nous avons eu une telle idée. Les cartes ont été notées directement sur le wiki (la carte de score est une page spécialement marquée), ces cartes ont collecté un plan à gros blocs, qui a été magnifiquement dessiné sous la forme d'un diagramme de Gantt.
Glossaire : la possibilité de visualiser les termes - explications des mots individuels d'une page - à partir d'un dictionnaire commun et de publier des entrées de dictionnaire sous forme de "pop-ups". Le dictionnaire lui-même est automatiquement collecté en bas de la page.
Graphiques : si vous avez besoin de dessiner un graphique simple, il est très simple de le faire en incorporant le bloc HTML à l'un des packages standard (Google Charts, HighCharts, etc.)
Tables : au-dessus de n'importe quelle table dans Confluence, vous pouvez "accrocher" Datatable - nous obtenons une table filtrée avec "pagination", très agréable et pratique.
La liste peut être prolongée suffisamment longtemps, pendant le fonctionnement, un inconvénient important a été constaté: les erreurs dans le code du serveur sont mal détectées - 500 erreurs sont mal visualisées et ne contiennent pratiquement aucune information. Sinon, expérimentez - c'est assez sûr.
Pour résumer
La manière simple décrite ci-dessus pour augmenter le dynamisme de Confluence vous permet de résoudre de nombreux problèmes différents. Pour l'utiliser, il ne nécessite pas d'outils et de compétences spéciaux. L'utilisation est suffisamment sûre. Je le recommande.
Dans le prochain article, je parlerai de l'expérience de l'utilisation de macros personnalisées dans Confluence - qui, à mon avis, peut vraiment être améliorée avec leur aide.
Tout est possible dans la programmation - une question de temps et de motivation seulement.