Aller au contenu
claude2odoo

L'xpath résout. Le module charge sans erreur. À l'écran, rien n'a bougé.

claude2odoo lit votre Odoo tel qu'il est, compare vos maquettes Claude Design à l'arbre de vues combiné, et écrit les vues d'héritage. Il refuse celles qu'Odoo rendrait inopérantes — et quand il refuse, il ne rend aucun fichier.

Odoo 17.0, 18.0 et 19.0. L'accès à votre instance est en lecture seule ; l'écriture passe par votre dépôt git.

Le moteur

Règles
0
Origine
pannes réelles
Niveaux
BLOQUANT · AVERTIR · VÉRIFIER
Versions
17.0 · 18.0 · 19.0
Instance
lecture seule
Écriture
votre dépôt git

Un constat bloquant retient le fichier entier : aucun XML n'est rendu tant qu'il subsiste.

Le temps ne part pas dans le code, il part à chercher pourquoi

Un chantier de thème Odoo a duré trois semaines. L'essentiel n'a pas été perdu à écrire des vues : il a été perdu à comprendre pourquoi une modification parfaitement valide ne s'affichait pas. Rien dans les journaux, rien dans l'éditeur, rien à l'écran. Les trente-trois règles du moteur sont l'autopsie de ces incidents, un par un.

RègleCe qui s'est passé, et pourquoi rien ne l'a signalé
A3 Une classe ajoutée à côté d'un t-attf-class. L'expression est évaluée au rendu et repose l'attribut entier. L'xpath résout, la classe est dans l'arbre combiné, le fichier charge — et une modification d'attribut qui ne modifie rien ne se signale nulle part.
A4 #products_grid_before visé comme un <div> : c'est un <aside>. L'xpath ne résout pas, la combinaison de la vue entière échoue, la page répond 500. Trois pannes du même chantier, même cause : l'identifiant lu dans le rendu, la balise supposée.
B2 Un build de production portait 24 copies COW, dont website.homepage et six en-têtes website_sale. La copie masque la vue générique : l'héritage n'atteint plus la page. On corrige, on recharge, rien ne bouge, on recorrige.
A8 s_newsletter_subscribe_form surchargé pour une seule page a levé une erreur à chaque ouverture de l'éditeur, sur trois sites qui n'avaient rien à voir avec le chantier.

Aucune de ces règles n'a été écrite par précaution. Chacune a coûté des jours à quelqu'un.

Ce qu'il écrit, et ce qu'il refuse d'écrire

Une même maquette, passée sur les sources réelles d'Odoo 18.0, cible website.layout. D'abord la sortie du moteur. Ensuite la même maquette avec une classe de plus sur le bandeau — et plus rien ne sort.

La vue d'héritage produite

rendu
<odoo>
    <!-- Généré par claude2odoo depuis la maquette. Chaque valeur
         vient du nœud indiqué : rien n'est inventé (règle E5). -->
    <template id="maquette_appliquee" inherit_id="website.layout">
        <!-- ajout de ['container-fluid', 'px-5'] · maquette:header#top/div#o_main_nav -->
        <xpath expr="//div[@id='o_main_nav']" position="attributes">
            <attribute name="class" add="container-fluid px-5" separator=" "/>
        </xpath>
        <!-- « I agree » → « Tout accepter » · maquette:div#website_cookies_bar/a#cookies-consent-all -->
        <xpath expr="//a[@id='cookies-consent-all']" position="replace">
            <a href="#" id="cookies-consent-all" role="button" class="js_close_popup btn btn-outline-primary rounded-circle btn-sm mb-2">Tout accepter</a>
        </xpath>
    </template>
</odoo>

Chaque xpath porte en commentaire le nœud de maquette d'où sort sa valeur : six mois plus tard, on remonte de la ligne au dessin. L'ancre est vérifiée unique contre l'arbre combiné avant de sortir, et la balise vient de l'arbre, jamais d'une supposition. Le replace reproduit le nœud lu dans Odoo, texte changé — les classes qu'il n'a pas lues, il ne les invente pas ; il les ajoute à part.

La même maquette, une classe de plus

rien n'est rendu

Sur website.layout en 18.0, header#top n'a pas d'attribut class : il n'a qu'un t-attf-class. Poser une ombre sur le bandeau depuis la maquette est le geste le plus banal d'un chantier de thème.

BLOQUANT · A3
la maquette ajoute ['shadow-sm'] à un élément dont le class est reposé au rendu par un t-attf-class
le t-attf-class est évalué au rendu et écrase le class statique en entier : l'xpath résout, la classe est dans l'arbre, et rien ne s'affiche
ajouter à t-attf-class au lieu de class
Un seul BLOQUANT retient le fichier Pas un XML grisé, pas un avertissement en bas de page : rien. Les deux écritures ci-dessus, parfaitement valides, ne sortent pas non plus. La tentation de coller quand même est trop forte un vendredi soir.

Ce qu'il ne fera jamais

  • Supprimer. Un élément présent dans Odoo et absent de la maquette produit un constat, jamais une suppression.
  • Inventer une valeur. Un prix, une durée, une certification qu'il n'a lus nulle part sont affichés « donnée manquante ». Une écriture sans provenance est refusée.
  • Surcharger un template partagé. L'effet déborde sur des pages étrangères au chantier.
  • Rendre un XML qu'il n'a pas su relire. Un -- venu d'une URL de maquette fait rejeter le fichier entier par l'analyseur d'Odoo, et le module ne charge plus.
VÉRIFIER · A12
13 élément(s) présents dans Odoo et absents de la maquette
le moteur ne propose jamais de suppression : remplacer un conteneur casse les vues sœurs sans lever d'erreur
décider à la main si ces éléments doivent disparaître

Quatre étapes, dans cet ordre

L'outil n'est pas un catalogue de fonctions, c'est une marche à suivre. On ne passe pas à la suivante sans que la précédente tienne.

01

Maquette

Vos fichiers .dc.html, un par page. L'en-tête et le pied sont des pages à part entière. Les pages sans maquette — panier, fiche produit — s'ajoutent ici en désignant leur template Odoo.

02

Odoo

L'instance à lire, le dépôt, la branche de staging et celle de production — distinctes. Le relevé des modules installés conditionne la justesse de la règle A8 : sans lui, elle répond sur le mauvais jeu de modules.

03

Intégration

Page par page : les écritures proposées, ce sur quoi chaque ancre tient, les constats, la vue d'héritage à écrire, et un fil de discussion pour trancher.

04

Déploiement

Staging d'abord. La production est fermée par construction : elle refuse s'il manque le dépôt, la branche, un staging réussi et validé à la main, ou si les deux branches sont la même.

Tarifs

Rien ne se paie au compte : tout se paie au chantier. Un chantier, c'est une maquette portée dans un Odoo — ses pages, ses écritures d'héritage, ses passages. Trois chantiers de front, c'est trois couvertures séparées.

La facturation n'est pas encore activée Toutes les fonctions sont ouvertes en attendant. Les montants ci-dessous sont indicatifs.

Essai

sans carte
gratuit / 14 jours

14 jours pour voir le moteur tourner sur votre propre Odoo, sans carte bancaire

un chantier, 3 pages de maquette comparées, 5 audits par mois. Les passages sont fermés : écrire dans votre Odoo, c'est le livrable.

Forfait d'intégration

indicatif
1 900 € / une fois

un chantier : une maquette Claude Design portée dans un Odoo

toutes les pages de la maquette, toutes les écritures d'héritage, tous les passages — sans plafond, pendant 90 jours.

Mises à jour

indicatif
90 € / mois

garder un chantier vivant après l'intégration

la recomparaison, les passages, et 2 nouvelles pages Claude Design par mois. Pas l'intégration d'une nouvelle maquette : refaire le site, c'est un nouveau forfait.

Comment ça se paie, en trois phrases

  • L'intégration se paie une fois, par chantier. Le forfait ouvre le chantier en entier : toutes les pages de la maquette, toutes les écritures produites, tous les passages, sans plafond.
  • Les mises à jour se paient au mois, par chantier. Quand la maquette change, on recompare et on repasse. Remplacer une maquette existante ne consomme rien : c'est exactement le travail que l'abonnement paie.
  • Refaire le site, c'est un nouveau forfait. L'abonnement garde un chantier vivant, il n'intègre pas une nouvelle maquette. Un chantier payé n'oblige jamais à prendre l'abonnement, et l'arrêter n'efface rien.

Si vous arrêtez de payer

  • Rien n'est effacé. Pages, vues proposées et fils de discussion restent lisibles et téléchargeables.
  • Un passage déjà préparé peut être clôturé et validé : personne ne reste avec un déploiement à moitié fait.
  • Ce qui se ferme, c'est ce qui relance le travail : importer, comparer, préparer un passage.
  • Une carte qui expire n'est pas un défaut de paiement : rien ne coupe tant que Stripe la relance.

Montants hors taxes ; la TVA est calculée au paiement et une facture est émise pour chaque règlement. Le paiement, les factures et la résiliation sont tenus par Stripe : aucun numéro de carte ne transite par nos serveurs.

Ce qui n'est jamais derrière un paiement

Faire payer une sûreté, c'est donner une raison de s'en passer.

Quelle que soit la formule, essai compris

  • Le refus d'écrire une vue inopérante. Ancre ambiguë, classe écrasée par un t-attf-class, surcharge qui déborde sur d'autres modules : c'est refusé pour tout le monde, tout le temps.
  • L'exigence d'un staging validé avant la production. Elle n'est pas une option de plan, c'est une fermeture de la route.
  • La sauvegarde avant écriture. Une sauvegarde prise après coup ne sauve rien.
  • La clôture du chantier et son attestation d'effacement. Partir doit rester possible sans payer.
  • La lecture seule sur votre instance. C'est une propriété du produit, pas une ligne de formule.

Et si vous n'êtes pas d'accord avec ce qu'il propose ?

Le moteur propose ; il n'applique pas. Rien ne part sans qu'on décide, et la décision se prend par écrit : chaque page a son fil de discussion, plus un fil global au chantier. Six mois plus tard, c'est la seule trace de pourquoi une vue est écrite comme elle l'est.

Un AVERTIR n'est pas un obstacle : c'est une décision à prendre et à consigner. Un VÉRIFIER passe et vous laisse un contrôle à faire sur le staging.

Le XML est à vous : c'est un fichier de votre module, dans votre dépôt. Vous le modifiez, vous le refusez, vous le réécrivez. Nous n'écrivons jamais dans votre instance.

Le seul point sur lequel il ne cède pas est le BLOQUANT — et il ne cède pas en rendant un fichier partiel : il ne rend rien. Corriger la cause et relancer la comparaison coûte moins cher que de chercher, trois jours plus tard, pourquoi la page n'a pas bougé.

Ce n'est pas votre Odoo que vous nous confiez, c'est celui de votre client

C'est l'objection à traiter en premier, et elle ne se traite pas par une promesse : elle se traite par ce qui disparaît, et par ce qui n'a jamais été écrit.

À la clôture, il ne reste rien

  • Vous déclarez le chantier terminé, et tout part : les maquettes et leur contenu, les comparaisons, le XML proposé, les discussions, le journal des passages, et jusqu'aux coordonnées de l'instance — qui disent chez qui le chantier a eu lieu.
  • Il reste une attestation d'effacement : le nom du chantier, ses dates, le décompte de ce qui est parti. Rien du contenu. Sans elle vous n'auriez que notre parole ; avec le contenu, il n'y aurait pas d'effacement. Vous pouvez la supprimer aussi.
  • Vos clés API ne sont pas concernées : elles n'ont jamais été enregistrées, ni écrites dans un journal. Elles sont demandées à chaque opération et oubliées à la fin de la requête.

Versions et accès

  • Odoo 17.0, 18.0 et 19.0, éprouvés sur les sources réelles de chacune : la même maquette y produit la même écriture, à la même ancre.
  • Les deux seuls points de couplage du produit — web.assets_frontend_lazy pour la purge du bundle, theme.ir.ui.view pour le reapply — existent sous le même nom dans les trois.
  • La lecture de votre instance passe par un accès en lecture seule. L'écriture passe par votre dépôt git, sous votre contrôle.

Le juger sur votre Odoo, pas sur une démonstration

14 jours, sans carte bancaire. Branchez-le sur votre instance, avec vos maquettes, sur les pages qui vous posent problème — y compris, et surtout, quand il refuse d'écrire. Un refus vous dit tout de suite ce qu'un chantier vous ferait découvrir après coup, sur une page en ligne.