Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Python et Zope et ZPT

22 réponses
Avatar
Dominique Crétel
Bonjour à tous,

Le post « Accès à une liste triée de doublet » m'a beaucoup aidé à
comprendre le fonctionnement des listes.

De plus, j'ai découvert des fonctions fortes intéressantes comme zip,
iter, etc...

Je pense que ce post est à la limite du hors sujet (Python) mais vu le
peu d'informations sur Zope/Python/TAL ......

Alors, excusez-moi si c'est le cas.

Voilà :

Je suis confronté à un problème difficile pour moi.
Le voilà.
J'ai la structure suivante (vu en partie dans le post précédant « Accès
à une liste triée de doublet »), que je ne peux _pas_ modifier (cf.
ci-dessous).
Et je dois aus sein d'un template python (.pt) faire en sorte de
récupérer quelque chose comme ça :

Zope Page Template
==================

<ul>
<li><a href="path11" class="menu6">
<img alt="title11" src="path11.jpg" class="menu1">
</a>
<ul>
<li><a href="subpath111" class="menu7">subtitle111</a></li>
<li><a href="subpath112" class="menu7">subtitle112</a></li>
<li><a href="subpath113" class="menu7">subtitle113</a></li>
<li><a href="subpath114" class="menu7">subtitle114</a></li>
<li><a href="subpath115" class="menu7">subtitle115</a></li>
</ul>
</li>
</ul>

Je réussi pas à utiliser les informations apprises dans le post précédant !
De plus et en plus d'utiliser Python, il faudra utiliser le ZPT (Zope
Python Template language).
Je ne m'en sort pas !
Le problème est de récupérer, à la fois, le titre et le chemin dans un
boucle tal:repeat !!!
Quelqu'un peut-il m'aider ???
MERCI.

Contenu de la liste (Python)
============================

liste =
[
[ # sub tree 1
[ # sub sub tree 1
'title11', 'path11',
'subtitle111', 'subpath111',
'subtitle112', 'subpath112',
'subtitle113', 'subpath113',
'subtitle114', 'subpath114',
'subtitle115', 'subpath115',
],
[ # sub sub tree 2
'title12', 'path12',
'subtitle121', 'subpath121',
'subtitle122', 'subpath122',
'subtitle123', 'subpath123',
'subtitle124', 'subpath124',
'subtitle125', 'subpath125',
]
],
[ # sub tree 2
[ # sub sub tree 1
'title21', 'path21',
'subtitle211', 'subpath211',
'subtitle212', 'subpath212',
'subtitle213', 'subpath213',
'subtitle214', 'subpath214',
'subtitle215', 'subpath215',
],
[ # sub sub tree 2
'title22', 'path22',
'subtitle221', 'subpath221',
'subtitle222', 'subpath222',
'subtitle223', 'subpath223',
'subtitle224', 'subpath224',
'subtitle225', 'subpath225',
],
[ # sub sub tree 3
'title23', 'path23',
'subtitle231', 'subpath231',
'subtitle232', 'subpath232',
'subtitle233', 'subpath233',
'subtitle234', 'subpath234',
'subtitle235', 'subpath235',
]
],
[ # sub tree 3
[# sub sub tree 1
'title31', 'path31',
'subtitle311', 'subpath311',
'subtitle312', 'subpath312',
'subtitle313', 'subpath313',
'subtitle314', 'subpath314',
'subtitle315', 'subpath315',
]
],
]

10 réponses

1 2 3
Avatar
Laurent Pointal
Bonjour à tous,
...<zip>...

Je réussi pas à utiliser les informations apprises dans le post précédant !
De plus et en plus d'utiliser Python, il faudra utiliser le ZPT (Zope
Python Template language).


[avec mon peu d'expérience sur Zope et les ZPT]

Normalement, tu peux définir et utiliser des fonctions Python pures dans
Zope (définies dans des fichiers externes que tu places dans un
répertoire ad-hoc). Si tu as des fonctionnement récursifs et des choses
un peu complexes, c'est peut-être la voie à prendre.

Mais il y aura peut-être un gourou de chez logilab pour t'indiquer une
piste (essaie de poster sur la liste python-fr aussi, au cas où, cf
http://www.aful.org/wws/info/python ).

A+

Laurent.

Avatar
bruno at modulix
Dominique Crétel wrote:
Bonjour à tous,

Le post « Accès à une liste triée de doublet » m'a beaucoup aidé à
comprendre le fonctionnement des listes.

De plus, j'ai découvert des fonctions fortes intéressantes comme zip,
iter, etc...


Attention quand même aux versions de Python. Jusqu'à très récemment,
Zope se base sur Python 2.3.x, il y a donc des idiomes dans le thread en
question qui ne seront pas utilisables... Mais ça ne devrait pas être un
pb en l'occurrence...

Je pense que ce post est à la limite du hors sujet (Python) mais vu le
peu d'informations sur Zope/Python/TAL ......

Alors, excusez-moi si c'est le cas.
<meta disclamer="AMHA">

Il n'y a pas à ma connaissance de ng ou ml francophone sur Zope, et je
pense que le trafic ici est suffisament bas pour qu'on n'ai pas besoin
de faire du tri...
</meta>

Voilà :

Je suis confronté à un problème difficile pour moi.
J'ai la structure suivante (vu en partie dans le post précédant « Accès
à une liste triée de doublet »), que je ne peux _pas_ modifier (cf.
ci-dessous).


Tu ne peux pas obtenir la liste sous la forme qui te conviens, mais tu
peux toujours restructurer la chose !-)


Et je dois aus sein d'un template python (.pt) faire en sorte de
récupérer quelque chose comme ça :

Zope Page Template
================= >
<ul>
<li><a href="path11" class="menu6">
<img alt="title11" src="path11.jpg" class="menu1">
</a>
<ul>
<li><a href="subpath111" class="menu7">subtitle111</a></li>
<li><a href="subpath112" class="menu7">subtitle112</a></li>
<li><a href="subpath113" class="menu7">subtitle113</a></li>
<li><a href="subpath114" class="menu7">subtitle114</a></li>
<li><a href="subpath115" class="menu7">subtitle115</a></li>
</ul>
</li>
</ul>

Je réussi pas à utiliser les informations apprises dans le post précédant !
De plus et en plus d'utiliser Python, il faudra utiliser le ZPT (Zope
Python Template language).


Ce n'est un problème que si tu essaie d'utiliser TAL comme un langage de
programmation, ce qu'il n'est pas. Avec Zope/ZPT, le principe général
est de garder les templates aussi simples que possible, et d'utiliser
des scripts pour formater les données quand nécessaire (c'est à dire
assez souvent...).

Je ne m'en sort pas !
Le problème est de récupérer, à la fois, le titre et le chemin dans un
boucle tal:repeat !!!
Quelqu'un peut-il m'aider ???


cf plus bas !-)

Contenu de la liste (Python)
=========================== >
liste > [
[ # sub tree 1
[ # sub sub tree 1
'title11', 'path11',
'subtitle111', 'subpath111',
'subtitle112', 'subpath112',
'subtitle113', 'subpath113',
'subtitle114', 'subpath114',
'subtitle115', 'subpath115',
],
[ # sub sub tree 2
'title12', 'path12',
'subtitle121', 'subpath121',
'subtitle122', 'subpath122',
'subtitle123', 'subpath123',
'subtitle124', 'subpath124',
'subtitle125', 'subpath125',
]
],
[ # sub tree 2
[ # sub sub tree 1
'title21', 'path21',
'subtitle211', 'subpath211',
'subtitle212', 'subpath212',
'subtitle213', 'subpath213',
'subtitle214', 'subpath214',
'subtitle215', 'subpath215',
],
[ # sub sub tree 2
'title22', 'path22',
'subtitle221', 'subpath221',
'subtitle222', 'subpath222',
'subtitle223', 'subpath223',
'subtitle224', 'subpath224',
'subtitle225', 'subpath225',
],
[ # sub sub tree 3
'title23', 'path23',
'subtitle231', 'subpath231',
'subtitle232', 'subpath232',
'subtitle233', 'subpath233',
'subtitle234', 'subpath234',
'subtitle235', 'subpath235',
]
],
[ # sub tree 3
[# sub sub tree 1
'title31', 'path31',
'subtitle311', 'subpath311',
'subtitle312', 'subpath312',
'subtitle313', 'subpath313',
'subtitle314', 'subpath314',
'subtitle315', 'subpath315',
]
],
]


On va déjà voir le template *sans tenir compte de la structure de la
liste*. L'idée est que le template soit le plus simple possible - c'est
en fait le template qui définit la structure de donnée nécessaire - on
verra *après* comment reformater les données pour que ça colle...

# menu.zpt
<!-- list2menu est le script python chargé de reformater la liste -->
<tal:block define="menu python: here.list2menu(the_list)">
<ul tal:repeat="sub_tree menu">
<tal:block define="sub_header sub_tree/header;
sub_entries sub_tree/entries">
<li><a class="menu6" tal:attributes="href sub_header/path">
<img class="menu1" tal:attributes="alt sub_header/title;
src sub_header/src" >
</a>
<ul tal:condition="sub_entries">
<li tal:repeat="entry sub_entries">
<a class="menu7"
tal:attributes="href entry/path"
tal:content="entry/title">subtitle</a>
</li>
</ul>
</li>
</tal:block>
</ul>
</tal:block>

Maintenant qu'on a un template à peu près lisible, il ne reste plus qu'à
implémenter le script qui va transformer ta liste en une structure de
données plus simplement utilisable, ie :

[{
'header': {'path' : 'pathXX',
'title': 'titleXX',
'src': 'pathXX.jpg'},
'entries': [ {'path': 'pathXXX', 'title': 'titleXXX'},
{'path': 'pathXXY', 'title': 'titleXXY'},
# etc...
]
},
# etc...
]

Allonzo :

## list2menu.py
## params=liste
menu = []
for subtree in liste[:]:
for sublist in subtree:
# la première entrée est "l'entête" de menu
title, path = sublist.pop(0), sublist.pop(0)
header = {'path' : path, 'title': title, 'src' : '%s.jpg' % path}

# les entrées suivantes sont les éléments du menu
entries = []
while sublist:
title, path = sublist.pop(0), sublist.pop(0)
entries.append({'title': title, 'path': path})

menu.append({'header': header, 'entries': entries})

return menu


Voili voilà... Je n'ai pas testé, il se peut donc qu'il y a des ptits
pains à droite à gauche, mais au moins ça te donne l'idée générale.


NB : Je suis parti du principe que tu voulais afficher toute la liste.
Si ce n'est pas le cas, à toi de modifier en fonction de tes besoins.

HTH
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"

Avatar
bruno at modulix
Laurent Pointal wrote:

Bonjour à tous,


...<zip>...

Je réussi pas à utiliser les informations apprises dans le post précédant !
De plus et en plus d'utiliser Python, il faudra utiliser le ZPT (Zope
Python Template language).



[avec mon peu d'expérience sur Zope et les ZPT]

Normalement, tu peux définir et utiliser des fonctions Python pures dans
Zope (définies dans des fichiers externes que tu places dans un
répertoire ad-hoc).


Je confirme (hint: "External method"), mais ce n'est pas forcément
nécessaire ici.

Si tu as des fonctionnement récursifs et des choses
un peu complexes, c'est peut-être la voie à prendre.


Si tu a vraiment des "choses un peu complexes" à faire, il est
généralement préférable d'écrire un "Produit" Zope (lequel peux
d'ailleurs comprendre des "External Methods").

A vrai dire, il est AMHA toujours préférable d'écrire un (ou des)
"produits" Zope, même s'ils se contentent de créer des scripts,
templates, external methods etc dans la ZODB. Cela permet de garder le
code sous contrôle de version...


--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"


Avatar
Dominique Crétel
Voili voilà... Je n'ai pas testé, il se peut donc qu'il y a des ptits
pains à droite à gauche, mais au moins ça te donne l'idée générale.


Un très très grand M E R C I pour ton aide Bruno !

C'est bien la première fois depuis que j'ai commencé à faire du Zope/ZPT
que je commence à entrevoir un début de compréhension !!!

NB : Je suis parti du principe que tu voulais afficher toute la liste.
Si ce n'est pas le cas, à toi de modifier en fonction de tes besoins.


Maintenant, comme tu l'as deviné, si je veux afficher le menu liste[0] à
un endroit, le menu liste[1] à un autre; puis-je faire comme ça ?

<!-- le 1er menu -->
<tal:block define="menu python: here.list2menu(liste[0])">
<ul tal:repeat="sub_tree menu">
<tal:block define="sub_header sub_tree/header;
sub_entries sub_tree/entries">
<li><a class="menu6" tal:attributes="href sub_header/path">
<img class="menu1" tal:attributes="alt sub_header/title;
src sub_header/src" >
</a>
<ul tal:condition="sub_entries">
<li tal:repeat="entry sub_entries">
<a class="menu7"
tal:attributes="href entry/path"
tal:content="entry/title">subtitle</a>
</li>
</ul>
</li>
</tal:block>
</ul>
</tal:block>

<!-- le 2ème menu -->
<tal:block define="menu python: here.list2menu(liste[1])">
<ul tal:repeat="sub_tree menu">
<tal:block define="sub_header sub_tree/header;
sub_entries sub_tree/entries">
<li><a class="menu6" tal:attributes="href sub_header/path">
<img class="menu1" tal:attributes="alt sub_header/title;
src sub_header/src" >
</a>
<ul tal:condition="sub_entries">
<li tal:repeat="entry sub_entries">
<a class="menu7"
tal:attributes="href entry/path"
tal:content="entry/title">subtitle</a>
</li>
</ul>
</li>
</tal:block>
</ul>
</tal:block>


Je pense que je vais devoir modifier ce ZPT ?

Avatar
Dominique Crétel
Oups, je pense avoir trouvé la solution !!!

Il suffit de faire :

<!-- le 1er menu -->
<tal:block define="menu python: here.list2menu([liste[0]])">
...


<!-- le 2ème menu -->
<tal:block define="menu python: here.list2menu([liste[1]])">
...


C'est ça ?

Avatar
bruno at modulix
Dominique Crétel wrote:
Oups, je pense avoir trouvé la solution !!!

Il suffit de faire :

<!-- le 1er menu -->
<tal:block define="menu python: here.list2menu([liste[0]])">


...

<!-- le 2ème menu -->
<tal:block define="menu python: here.list2menu([liste[1]])">


...

C'est ça ?


A ta place, je modifierais surtout le script list2menu pour tenir compte
du niveau d'imbrication en moins !-)

(hint : il suffit d'enlever la boucle externe)

BTW, je ne sais pas comment tu a organisé tes templates, mais le cas
échéant, copier/coller reste une mauvaise idée. Il vaut mieux factoriser
le bout de template à réutiliser dans un ZPT séparé, et le rappeller
depuis le template principal (en lui passant la sous-liste à afficher en
paramètre)


--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"


Avatar
Dominique Crétel
Dominique Crétel wrote:
Oups, je pense avoir trouvé la solution !!!

Il suffit de faire :

<!-- le 1er menu -->
<tal:block define="menu python: here.list2menu([liste[0]])">
...


<!-- le 2ème menu -->
<tal:block define="menu python: here.list2menu([liste[1]])">
...


C'est ça ?


A ta place, je modifierais surtout le script list2menu pour tenir compte
du niveau d'imbrication en moins !-)

(hint : il suffit d'enlever la boucle externe)

BTW, je ne sais pas comment tu a organisé tes templates, mais le cas
échéant, copier/coller reste une mauvaise idée. Il vaut mieux factoriser
le bout de template à réutiliser dans un ZPT séparé, et le rappeller
depuis le template principal (en lui passant la sous-liste à afficher en
paramètre)




En fait, la présentation de chaque menu doit changer un peu, donc la
recopie me va.

Par contre, je suis en train de me battre avec le template pour éviter
d'avoir la fermeture </ul> suivi de l'ouverture <ul> dans le niveau le
plus haut. Et je n'y arrive pas !

Par exemple, avoir :

<ul>
<li><a href="path11" class="menu6">
<img alt="title11" src="path11.jpg" class="menu1">
</a>
<ul>
<li><a href="subpath111" class="menu7">subtitle111</a></li>
<li><a href="subpath112" class="menu7">subtitle112</a></li>
<li><a href="subpath113" class="menu7">subtitle113</a></li>
<li><a href="subpath114" class="menu7">subtitle114</a></li>
<li><a href="subpath115" class="menu7">subtitle115</a></li>
</ul>
</li>
<!-- dans un même menu, pas de </ul><ul> !!! -->
<li><a href="path12" class="menu6">
<img alt="title12" src="path12.jpg" class="menu1">
</a>
<ul>
<li><a href="subpath121" class="menu7">subtitle121</a></li>
<li><a href="subpath122" class="menu7">subtitle122</a></li>
<li><a href="subpath123" class="menu7">subtitle123</a></li>
<li><a href="subpath124" class="menu7">subtitle124</a></li>
<li><a href="subpath125" class="menu7">subtitle125</a></li>
</ul>
</li>
</ul>
<ul>
<li><a href="path21" class="menu6">
<img alt="title21" src="path21.jpg" class="menu1">
</a>
<ul>
<li><a href="subpath211" class="menu7">subtitle211</a></li>
<li><a href="subpath212" class="menu7">subtitle212</a></li>
<li><a href="subpath213" class="menu7">subtitle213</a></li>
<li><a href="subpath214" class="menu7">subtitle214</a></li>
<li><a href="subpath215" class="menu7">subtitle215</a></li>
</ul>
</li>
</ul>



Avatar
bruno at modulix
Dominique Crétel wrote:

Dominique Crétel wrote:

Oups, je pense avoir trouvé la solution !!!

Il suffit de faire :

<!-- le 1er menu -->
<tal:block define="menu python: here.list2menu([liste[0]])">


...

<!-- le 2ème menu -->
<tal:block define="menu python: here.list2menu([liste[1]])">


...

C'est ça ?



A ta place, je modifierais surtout le script list2menu pour tenir compte
du niveau d'imbrication en moins !-)

(hint : il suffit d'enlever la boucle externe)

BTW, je ne sais pas comment tu a organisé tes templates, mais le cas
échéant, copier/coller reste une mauvaise idée. Il vaut mieux factoriser
le bout de template à réutiliser dans un ZPT séparé, et le rappeller
depuis le template principal (en lui passant la sous-liste à afficher en
paramètre)




En fait, la présentation de chaque menu doit changer un peu, donc la
recopie me va.


Voire... si ça diverge suffisament, pourquoi pas, mais regarde quand
même si ces differences peuvent être facilement paramétrées...

Par contre, je suis en train de me battre avec le template pour éviter
d'avoir la fermeture </ul> suivi de l'ouverture <ul> dans le niveau le
plus haut. Et je n'y arrive pas !

Par exemple, avoir :

<ul>
<li><a href="path11" class="menu6">
<img alt="title11" src="path11.jpg" class="menu1">
</a>
<ul>
<li><a href="subpath111" class="menu7">subtitle111</a></li>
<li><a href="subpath112" class="menu7">subtitle112</a></li>
<li><a href="subpath113" class="menu7">subtitle113</a></li>
<li><a href="subpath114" class="menu7">subtitle114</a></li>
<li><a href="subpath115" class="menu7">subtitle115</a></li>
</ul>
</li>
<!-- dans un même menu, pas de </ul><ul> !!! -->
<li><a href="path12" class="menu6">
<img alt="title12" src="path12.jpg" class="menu1">
</a>
<ul>
<li><a href="subpath121" class="menu7">subtitle121</a></li>
<li><a href="subpath122" class="menu7">subtitle122</a></li>
<li><a href="subpath123" class="menu7">subtitle123</a></li>
<li><a href="subpath124" class="menu7">subtitle124</a></li>
<li><a href="subpath125" class="menu7">subtitle125</a></li>
</ul>
</li>
</ul>
<ul>
<li><a href="path21" class="menu6">
<img alt="title21" src="path21.jpg" class="menu1">
</a>
<ul>
<li><a href="subpath211" class="menu7">subtitle211</a></li>
<li><a href="subpath212" class="menu7">subtitle212</a></li>
<li><a href="subpath213" class="menu7">subtitle213</a></li>
<li><a href="subpath214" class="menu7">subtitle214</a></li>
<li><a href="subpath215" class="menu7">subtitle215</a></li>
</ul>
</li>
</ul>



Si tu a modifié le script pour lui passer les subtrees au lieu de la
liste complète, tu dois pouvoir régler ton problème en sortant les <ul/>
du template menu et en les mettant dans le template appelant... Sinon,
n'hésite pas à revoir le template et le script. L'exemple que je t'ai
donné ne tenait pas compte de ce type de besoin, puisque tu ne l'avais
pas exprimé, et je ne l'aurais peut-être pas implémenté de cette façon
le cas échéant. Bref, c'est plus un exemple qu'une solution 'clé-en-main'...

Rappelle-toi, avec TAL, il vaut mieux définir la structure de données
passée au template en fonction du besoin que le template en fonction de
la structure de données. Si les besoins de présentation changent, il est
clair que c'est à au script de s'adapter - il est là pour ça !-).

HTH
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"




Avatar
Dominique Crétel
Si tu a modifié le script pour lui passer les subtrees au lieu de la
liste complète, tu dois pouvoir régler ton problème en sortant les <ul/>
du template menu et en les mettant dans le template appelant... Sinon,
n'hésite pas à revoir le template et le script. L'exemple que je t'ai
donné ne tenait pas compte de ce type de besoin, puisque tu ne l'avais
pas exprimé, et je ne l'aurais peut-être pas implémenté de cette façon
le cas échéant. Bref, c'est plus un exemple qu'une solution 'clé-en-main'...


Tu as raison, je vais modifier le script Python

J'espère que je ne t'exaspère pas trop !?
Etant débutant, ma méconnaissance doit être quelque peu agaçante !

Oups ! J'obtiens l'erreur suivante dans Zope après avoir fait les
modifications ???

## Script (Python) "list2menu"
##bind container=container
##bind context=context
##bind namespace ##bind script=script
##bind subpath=traverse_subpath
##parameters ##title ##
## Errors:
## Script line 2
## for sublist liste[:]:
## ^
## SyntaxError: invalid syntax
##
menu = []
for sublist liste[:]:
# la première entrée est "l'entête" de menu
title, path = sublist.pop(0), sublist.pop(0)
header = {'path' : path, 'title': title}

# les entrées suivantes sont les éléments du menu
entries = []
while sublist:
title, path = sublist.pop(0), sublist.pop(0)
entries.append({'title': title, 'path': path})

menu.append({'header': header, 'entries': entries})

return menu

(Question: Pourquoi sous Zope, dois-je supprimer le script Python du
dossier custom, le reprendre dans le répertoire source python, le
modifier en le customisant, lui ajouter le paramètre, puis enfin faire
un save pour le récupérer enfin modifier dans le dossier custom ?)

Puis voilà le template modifié :

# menu.zpt
<!-- list2menu est le script python chargé de reformater la liste -->
<tal:block define="menu python:here.list2menu(liste[2])">
<li tal:repeat="sub_tree menu">
<tal:block define="sub_header sub_tree/header; sub_entries
sub_tree/entries">
<a class="menu6" tal:attributes="href sub_header/path"><img
class="menu1" alt="Pipo" src="pipo.jpg"></a>
<ul tal:condition="sub_entries">
<li tal:repeat="entry sub_entries"><a class="menu7"
tal:attributes="href entry/path" tal:content="entry/title">subtitle</a></li>
</ul>
</tal:block>
</li>
</tal:block>

Merci.

DC

Avatar
Dominique Crétel
for sublist liste[:]:


Oups! j'ai honte....

## for sublist in liste[:]:
## ^
## j'ai oublié le 'in'

Désolé !!!!

1 2 3