Probleme mit Pfad

Django, Flask, Bottle, WSGI, CGI…
Benutzeravatar
mitch
User
Beiträge: 78
Registriert: Dienstag 1. August 2006, 09:07
Kontaktdaten:

hi, es ist eine etwas einfachere Frage, ich will den User abfragen wie im :

Code: Alles auswählen

<html>
  <head>
    <title tal:content="template/title">The title</title>
  </head>
  <body>
    

     <b> -- Benutzerinformationen -- </b>

<div
  tal:omit-tag=""
  tal:define="
    userName request/userName|nothing;
    userObj python: here.portal_membership.getMemberById(userName);
    getPortrait nocall: here/../../portal_membership/getPersonalPortrait;
    getFolder nocall: here/../../portal_membership/getHomeFolder">
 
<p tal:condition="not: userName">
   kein Benutzername gewählt.
</p>
<p tal:condition="not: userObj">
   Dieser Benutzer existiert nicht.
</p>

<table tal:condition="userObj">
  <tr>
    <td>
     <img src=""
     tal:replace="structure python: getPortrait(userName)" />
<li 
   tal:define="home python: getFolder(userName)"
   tal:condition="home">
   <a href=""
       tal:attributes="href home/absolute_url"
       >Home Ordner</a>
</li>
    </td>
   </tr>
</table>
</div>
  </body>
</html>
Das Problem ist bloß, dass ich mich ja in meinem plone/portal_skins/costum Ordner befinde und die "portal_memberships" in der Struktur "plone/" liegen aber wie komme ich wieder den Pfad nach oben? Mit "here" gibt er halt den aktuellen Platz aus "container" aus wo er sich gerade befindet! Gibts da auch was wie bei html? So eine einfach Lösung wie "../" um ein Ordner höher zu gehen?!

edit: okay das mit dem Pfad in den Tags hab ich herraus gefunden .. "here/../" um Ordner höher zu gehen aber wie mache ich das im Python bei "here.portal_membership.getMemberById(userName);"

Sorry für die unanehmlichkeiten ... bin noch am lernen


mfg mitch...[

Edit by Gerold: Code-Tag gesetzt
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

mitch hat geschrieben:Das Problem ist bloß, dass ich mich ja in meinem plone/portal_skins/costum Ordner befinde und die "portal_memberships" in der Struktur "plone/" liegen aber wie komme ich wieder den Pfad nach oben?
Hi Mitch!

Zope beherrst "Aquisition". Dh. es sucht ein Objekt vom aufrufenden Ordner ausgehend bis zum Root-Ordner zurück, bis es das Objekt gefunden hat. Du brauchst dich also nicht darum kümmern, den absoluten Pfad zu einem Objekt angeben zu müssen.

``here/portal_membership`` genügt.

Code: Alles auswählen

<p tal:content="here/portal_membership/getHomeFolder" />
<p tal:define="home here/portal_membership/getHomeFolder" 
   tal:content="home/absolute_url"
/>
In einem "Python-Script" sieht das dann so aus:

Code: Alles auswählen

print context.portal_membership.getHomeFolder()
print context.portal_membership.getHomeFolder().absolute_url()

return printed
Willst du innerhalb eines "Python-Scriptes" wirklich einmal ganz gezielt auf den übergeordneten Ordner zugreifen, dann machst du das mit ``aq_parent``.

Code: Alles auswählen

print context.aq_parent.absolute_url()
print context.aq_parent.aq_parent.absolute_url()
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Da gibt es noch etwas...

Code: Alles auswählen

<div tal:omit-tag=""
     tal:define="userName request/userName | nothing;
                 userObj python: context.portal_membership.getMemberById(userName);
                 membershipObj context/portal_membership;
                 getPortrait nocall: membershipObj/getPersonalPortrait;
                 getFolder nocall: membershipObj/getHomeFolder"
>
Wenn du mehrmals auf ein entferntes Objekt zugreifen musst, dann ist es besser, wenn du es vorher einmal in eine Variable legst. Dann muss Zope nicht jedes mal neu nach dem Objekt suchen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
mitch
User
Beiträge: 78
Registriert: Dienstag 1. August 2006, 09:07
Kontaktdaten:

hallo gerold,

danke für deine Antwort, ich habe es jetzt mal so:
<html>
<head>
<title tal:content="template/title">The title</title>
</head>
<body>


<b> -- Benutzerinformationen -- </b>

<div
tal:omit-tag=""
tal:define="
userName string:mitch;
userObj python: here.portal_membership.getMemberById(userName);
membershipObj context/portal_membership;
getPortrait nocall: membershipObj/getPersonalPortrait;
getFolder nocall: membershipObj/getHomeFolder">

<p tal:condition="not: userName">
kein Benutzername gewählt.
</p>
<p tal:condition="not: userObj">
Dieser Benutzer existiert nicht.
</p>

<table tal:condition="userObj">
<tr>
<td>
<img src=""
tal:replace="structure python: getPortrait(userName)" />
<li
tal:define="home python: getFolder(userName)"
tal:condition="home">
<a href=""
tal:attributes="href home/absolute_url"
>Home Ordner</a>
</li>
</td>
</tr>
</table>
</div>
</body>
</html>
aber er gibt mir immer aus, dass der Benutzer nicht existiert obwohl er das tut! Was mache ich falsch? Ich habe das Beispiel aus einem Plonehandbuch was schon älter ist und ich arbeite mit der Version 2.5.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

mitch hat geschrieben:ich arbeite mit der Version 2.5.
Hi Mitch!

Da musste ich jetzt auch ein wenig herumexperimentiert um da drauf zu kommen. ``string:tester`` liefert nicht unbedingt ein String-Objekt zurück. Mit ``str()`` umwandeln, dann funktioniert es.

Code: Alles auswählen

<p tal:define="userName string:tester;
               membershipObj context/portal_membership;
               userObj python: membershipObj.getMemberById(str(userName));"
   tal:content="userObj"
/>
mfg
Gerold
:-)

PS: Bitte stell deinen Code zwischen zwei Code-Tags, damit man ihn besser lesen kann.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
mitch
User
Beiträge: 78
Registriert: Dienstag 1. August 2006, 09:07
Kontaktdaten:

Danke gerold für deine Hilfe es funktioniert jetzt...
Ich werd mich bestimmt noch öfters hier melden, dass mit code zeilen merk ich mir, sorry!
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Halli hallo!

Das mit dem aq_parent habe ich schon immer vermisst.
Nun habe ich mal wieder ein merkwürdiges Verhalten.
Im Customordner liegt ein Pythonscript:

Code: Alles auswählen

return context.aq_parent.aq_parent.km_manager.script_par_read('list', 'Programm', 'Vollmacht', 0)
Es lässt sich prima testen und gibt eine Liste zurück.

Ebenfalls im Ordner habe ich das Template prefs_groups_overview customized.
Es enthält in den ersten Zeilen folgenden tag:

Code: Alles auswählen

<tal:variable tal:omit-tag=""
	tal:define="KMMRoles python: context.script_KMM_vollmachten()">
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

AAA

Ich habe eben versehens auf Absenden und nicht Vorschau geklickt :-(

Also jedenfalls bekomme ich eine Fehlermeldung in Plone:
Fehlertyp
AttributeError

Fehlerwert
km_manager

In der Ordnerstruktur liegt ein Ploneordner hier:
portal-root/km_manager

Cutom liegt ja unter portal-root/portal_skins/custom

Rätsel: Warum mag Plone den Ordner nicht??

Ich grüße alle
Jamil
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Nochmal ich.

Ich habe eine Vermutung. Wenn ich das Script script_par_read in den Ordner custom lege geht es. Kann es sein, dass Plone oder Zope es nicht mag, wenn ein Ordner den string "manage" enthält?

Grüße
Jamil
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

JR hat geschrieben:

Code: Alles auswählen

return context.aq_parent.aq_parent.km_manager.script_par_read('list', 'Programm', 'Vollmacht', 0)
Hi JR!

Unabhängig von deinem Problem:

Es sollte aber ohne die ``aq_parent`` genauso, wenn nicht besser funktionieren. Absolute Angaben sollte man vermeiden.

Code: Alles auswählen

return context.km_manager.script_par_read('list', 'Programm', 'Vollmacht', 0)
Zope geht somit automatisch so weit nach oben, bis es das Objekt "km_manager" findet und führt dann das Skript ``script_par_read`` mit dem aktuellen Ordner, von dem aus gesucht wurde, als Context aus.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Gerold, du bist unglaublich schnell :-)

Ich möchte aus

portal/portal_skins/custom

ein Script benutzen, welches unter

portal/km_manager

liegt. Somit geht der Pfad nicht nur um Ebenen nach oben, sondern nach zwei Schritten hoch wieder einen Schritt von portal nach km_manager runter. Ich habe jetzt dieses Script, welches ich in den o.g. Verzeichnissen benötige einfach in den Portalrootordner gelegt. Ist allerdings keine gute Lösung, da es nicht so performant ist. Das Script rufe ich nämlich nur in wenigen Fällen aus dem custom-Ordner heraus auf. Viel häufiger werde ich es im Ordner km_manager benötigen.
Das Traversieren kostet glaube ich etwas Zeit und verlangsamt den Seitenaufbau nicht unerheblich.

Was sagt der Profi dazu?

Jamil
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

JR hat geschrieben:Fehlertyp
AttributeError

Fehlerwert
km_manager

In der Ordnerstruktur liegt ein Ploneordner hier:
portal-root/km_manager

Cutom liegt ja unter portal-root/portal_skins/custom
Hi JR!

**AttributeError** --> Attribut wurde nicht gefunden.
**Fehlerwert: km_manager** --> Dieses Objekt wurde nicht gefunden.

Code: Alles auswählen

<portal_root>/km_manager
<portal_root>/portal_skins/custom
VORSICHT! Diese Beiden Ordner sind in Plone **virtuell** auf gleicher Höhe. Deshalb solltest du in diesen Ordnern auch keine Objekte mit gleichen IDs erstellen.

Hier ein paar Beispiele zum Veranschaulichen:

Code: Alles auswählen

<portal_root>/meine_seitenvorlage
<portal_root>/portal_skins/custom/meine_seitenvorlage
Zwei Seitenvorlagen (meine_seitenvorlage). Eine davon in den <portal_root>-Ordner und eine davon in den <custom>-Ordner.

Gibst du den URL http://localhost:8080/<portal_root>/meine_seitenvorlage ein, dann wird dir immer die Seitenvorlage im <portal_root> angezeigt. Es gibt aber keine Möglichkeit, auf die Seitenvorlage im <custom>-Ordner zuzugreifen. --> Beide liegen virtuell auf gleicher Höhe und Plone versucht es zuerst im <portal_root>. Findet Plone dort die Seite, wird die Suche abgebrochen und die Seite angezeigt.
Löscht du nun die Seite im <portal_root>, dann sucht Plone in den Skins nach der Seite. Dazu sieht Plone in den Properties des Objektes ``<portal_root>/portal_skins`` nach, in welchem Ordner zuerst nachgesehen werden soll. --> das ist normalerweise der Ordner ``<portal_root>/portal_skins/custom``. Findet Plone dort die Seite, dann bricht es die Suche ab und gibt die Seite zurück. Findet Plone im <custom>-Ordner die Seite nicht, dann sieht es wieder in den Properties des Objektes ``<portal_root>/portal_skins`` nach, in welchem Ordner es weiter suchen soll. So "grast" Plone alle möglichen Ordner nach dem Objekt ab.

Dieses Verhalten ist auch der Grund, weshalb man, wenn man eine Plone-System-Seitenvorlage wie z.B. "main_template" ändern möchte, einfach eine Kopie der "main_template" in den <custom>-Ordner legt. So wird jetzt nicht mehr die "main_template" aus dem Ordner ``<portal_root>/portal_skins/plone_templates`` verwendet, da Plone die "main_template" zuerst im <custom>-Ordner findet und dann nicht mehr weiter sucht.

Fazit 1: Nichts direkt in den <portal_root>-Ordner legen, da das den Zugriff auf ein Objekt, mit gleichem Namen, im <custom>-Ordner versperren kann.

Fazit 2: ``aq_parent`` nur dann einsetzen, wenn ich unbedingt und gezielt auf den darunterliegenden Ordner zugreifen muss. Ansonsten ist es besser, die Acquisition von Zope arbeiten zu lassen.

lg
Gerold
:-)
Zuletzt geändert von gerold am Donnerstag 17. August 2006, 20:33, insgesamt 3-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

JR hat geschrieben:portal/portal_skins/custom
ein Script benutzen, welches unter
portal/km_manager
[...]
Das Traversieren kostet glaube ich etwas Zeit und verlangsamt den Seitenaufbau nicht unerheblich.
Hi Jamil!

Code: Alles auswählen

portal/km_manager 
portal/portal_skins/custom

Um aus dem Skript im <custom>-Ordner heraus, das Skript im ``<portal_root>/km_manager``-Ordner aufzurufen, nimmst du diesen Befehl:

Code: Alles auswählen

container.km_manager.mein_skript()
Traversieren (Akquisition) ist für Zope das Natürlichste der Welt. Wenn irgendwo alles getan wurde um Geschwindigkeit raus zu holen, dann hier. --> Nutze es!

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hi Gerold, vielen Dank für die ausführliche Beschreibung, aber dieses Prinzip habe ich verstanden und eingehalten. Vielleicht ist dies falsch rüber gekommen.

Es ist ganz einfach so:
Ich habe ein Script namens script_par_read, welches ich im ersten Versuch nur unter

Code: Alles auswählen

<portal-root>/km_manager
abgelegt habe.
Dieses Script verwende ich häufig in anderen Scripten welche im selben Ordner liegen mit

Code: Alles auswählen

context.script_par_read(...)
Das geht sehr schnell, da die Traversierung das Script schnell entdeckt.
Nun wollte ich aus

Code: Alles auswählen

<portal-root>/portal_skins/custom/prefs_groups_overview
heraus auf dieses Script

Code: Alles auswählen

<portal-root>/km_manager/script_par_read
zugreifen.
Dazu habe ich dann in der Seite

Code: Alles auswählen

<tal:variable tal:omit-tag="" 
    tal:define="KMMRoles python: context.aq_parent.aq_parent.km_manager.script_par_read(...)">
eingebaut und es kam zu dem besagten Fehler.
Derselbe Pythonbefehl

Code: Alles auswählen

context.aq_parent.aq_parent.km_manager.script_par_read(...)
funktionierte aber in einem Testscript, welches in demselben Ordner wie die Seite liegt !?

Grüße
Jamil
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hi Gerold,

während ich getippt habe, kam deine Nachricht. Ich versuche es mal so, wie du es beschrieben hast mit dem container und gebe gleich Feedback
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Es funzt!

Also wenn ich das jetzt richtig verstehe läuft es so. Bei context guckt Plone erst im selben Ordner und dann in den Ordnern nach oben bis zum portal-root. Wenn immer noch nix gefunden, dann nach dem Schema, wie du es beschrieben hast.

Was ist der Unterschied zum container direkt?

Und wieso klappt

Code: Alles auswählen

<tal:variable tal:omit-tag="" 
    tal:define="KMMRoles python: context.aq_parent.aq_parent.km_manager.script_par_read(...)">
in einem Script aber nicht in einer Seite, obwohl beide im selben Ordner liegen?

Plone macht Spaß ist aber nicht einfach :-)
Jamil
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

JR hat geschrieben:Was ist der Unterschied zum container direkt?

Und wieso klappt
``context.aq_parent.aq_parent.km_manager.script_par_read(...)"``
in einem Script aber nicht in einer Seite, obwohl beide im selben Ordner liegen?
Hi Jamil!

Es gibt Unterschiede beim Aufruf, die den Kontext ("context") verändern. Auch zwischen Seitenvorlagen, DTML-Methoden und DTML-Dokumenten gibt es beim Aufruf Unterschiede. --> ein DTML-Dokument gilt als eigenständiges Objekt und kann als "context" dienen, was DTML-Methoden und Seitenvorlagen nicht können.

Eine Seitenvorlage ist **kein angreifbares** Objekt -- es ist NUR eine Vorlage. Die Vorlage gehört zum Ordner in dem sie liegt.

Wird eine Seitenvorlage von einer anderen Seitenvorlage aus aufgerufen, dann ist der Ordner der *aufrufenden* Seitenvorlage der "context". Wird eine Seitenvorlage von einem DTML-Dokument aus aufgerufen, dann ist das DTML-Dokument selbst der "context".

Wenn du den Ausdruck ``context/mein_ordner/mein_skript`` von einer Seitenvorlage aus verwendest, dann stellt Zope erst einmal fest, was der ``context`` ist. Beim Aufruf aus einer einer Seitenvorlage heraus ist der ``context`` der Ordner, der aufrufenden Seitenvorlage. In diesem Ordner sucht Zope jetzt das Objekt ``mein_ordner``. Findet Zope dieses Objekt nicht, dann geht es einen Ordner nach oben und versucht es noch einmal. Sobald das Objekt ``mein_ordner`` gefunden wurde, wird versucht, auf ``mein_skript`` zuzugreifen.
Der Aufruf kann z.B. durch den URL ``http://localhost:8080/mein_ordner/noch_ ... ein_skript`` passieren. Dann ist in diesem Fall der Ordner ``mein_ordner/noch_ein_ordner`` der "context".

Der Kontainer ("container") ist immer der Ordner, **in dem die Seitenvorlage liegt**. Egal von wo aus die Seitenvorlage aufgerufen wurde.

Beim Aufruf durch den URL ``http://localhost:8080/mein_ordner/noch_ ... ein_skript`` ist der Ordner ``mein_ordner`` der "container", da in diesem Ordner die Seitenvorlage liegt.

Liegt die Seitenvorlage z.B. im ROOT-Ordner, wird diese aber von einem Ordner, unterhalb des Root-Ordners, aufgerufen, dann ist der Ordner, von dem aus die Seitenvorlage aufgerufen wurde der Kontext (context).

"context" ist abhängig vom Ort von dem aus die Seitenvorlage aufgerufen wird und ist innerhalb der aufgerufenen Seitenvorlage, im Normalfall, der Ordner **von dem aus** auf die Seitenvorlage zugegriffen wird.

"container" ist innerhalb der aufgerufenen Seitenvorlage immer der Ordner, in dem die Seitenvorlage liegt -- ändert sich also nicht.

"template" ist innerhalb der aufgerufenen Seitenvorlage (es gibt auch Seitenvorlagen, die nur als Kontainer für Macros dienen und nicht direkt aufgerufen werden), die Seitenvorlage selbst.

"script" ist innerhalb des aufgerufenen "Python-Scripts" das Skript selbst.

Hier noch zwei Skripte, mit denen du das auch austesten kannst:

my_pythonscript:

Code: Alles auswählen

print "context:", context.absolute_url()
print "container:", container.absolute_url()
print "script:", script.absolute_url()
print
print "context.aq_parent:", context.aq_parent.absolute_url()
print "container.aq_parent:", container.aq_parent.absolute_url()
print
print "Vorsicht ! ! !"
print "script.aq_parent:", script.aq_parent.absolute_url()

return printed
my_pagetemplate:

Code: Alles auswählen

<p>
  context oder here: <span tal:content="context/absolute_url" />
</p>
<p>
  container: <span tal:content="container/absolute_url" />
</p>
<p>
  template: <span tal:content="template/absolute_url" />
</p>
<p> </p>
<p>
  context/aq_parent: <span tal:content="context/aq_parent/absolute_url" />
</p>
<p>
  container/aq_parent: <span tal:content="container/aq_parent/absolute_url" />
</p>
<p>
  Vorsicht ! ! !<br />
  template/aq_parent: <span tal:content="template/aq_parent/absolute_url" />
</p>
Lege beide Skripte mal in einen Ordner, erstelle noch zwei verschachtelte Unterordner und rufe die Skripte aus diesen Ordnern auf.

z.B. so:

Code: Alles auswählen

http://localhost:8080/TESTORDNER/erster_unterordner/zweiter_unterordner/my_pagetemplate
http://localhost:8080/TESTORDNER/erster_unterordner/zweiter_unterordner/my_pythonscript
In diesem Fall sollten die Skripte "my_pythonscript" und "my_pagetemplate" im Ordner "TESTORDNER" liegen. Dann ist die Aussagekraft ziemlich groß.

Vorsicht -- jetzt wirds hammerhart! :-)
Erstelle dir noch einen Ordner. Diesmal TESTORDNER2 und erstelle unterhalb dieses Ordners wieder zwei Unterordner.

Das Ganze sollte dann so aussehen:

Code: Alles auswählen

/
|- TESTORDNER
|   |- erster_unterordner
|   |   |- zweiter_unterordner
|   |
|   |- my_pythonscript
|   |- my_pagetemplate
|
|- TESTORDNER2
    |- erster_unterordner
        |- zweiter_unterordner
Rufe jetzt die Skripte so auf:

Code: Alles auswählen

http://localhost:8080/TESTORDNER/TESTORDNER2/erster_unterordner/zweiter_unterordner/my_pagetemplate
http://localhost:8080/TESTORDNER/TESTORDNER2/erster_unterordner/zweiter_unterordner/my_pythonscript
Zuerst zeigen wir damit Zope, in welchem Ordner die Skripte liegen, die wir aufrufen möchten. Und dann zeigen wir Zope noch, was unser "context" ist. :twisted:

Dieser Link erklärt die Sachlage noch einmal ausführlich: http://www.dzug.org/Members/vbachs/zboo ... leexamples

Ich bin mir sicher, dass es viele gibt, die diese Seite mehrmals durchlesen mussten. :twisted:

Warum das alles?
So kompliziert es auch im ersten Moment erscheinen mag. So viele Vorteile bringt die Unterscheidung des Kontexts auch.

Stell dir vor, du hast eine Seitenvorlage die in deinem Hauptordner liegt. Die Daten hinterlegst du als "Properties" und Objekte (z.B. Bilder) in den einzelnen Ordnern. Je nach Aufruf wird dann der Seitenvorlage mitgeteilt, in welchem Ordner sich der Inhalt befindet, mit dem die Seitenvorlage befüllt werden soll.

Diese, in meinen Augen, wunderbare Art, den Inhalt von den Vorlagen zu trennen, muss ein anderes Framework Zope erst einmal nachmachen. ;-)

Ach ja -- es geht ja noch weiter...

Stell dir vor, du hast einen Ordner in dem die Seiten komplett anders aussehen sollen. Du musst nichts am Kontent ändern. -- Einfach die Haupt-Seitenvorlage in diesen Ordner kopieren und anpassen. Durch die Akquisition, greift Zope in diesem Ordner und in allen Unterordnern dieses Ordners nicht mehr auf die Haupt-Seitenvorlage zu, sondern auf die Seitenvorlage, die Zope in diesem Ordner findet.

So können auch Stylesheets explizit nur für einen Ordner angepasst werden. Für alle anderen Ordner gilt dann trotzdem noch das Haupt-Stylesheet... Bilder, Header, Footer, ...

lg
Gerold
:-)
Zuletzt geändert von gerold am Freitag 18. August 2006, 11:11, insgesamt 2-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hallo Gerold!

Bin gerade aufgestanden und muss erstmal für jemand anderen programmieren gehen :-)

Werd mir das aber auf jedem Fall in Ruhe durchlesen und nachvollziehen, denn dieses Prinzip ist echt essentiell.

Anmerkung:
Du hast mir mal beim Einbinden einer Stylesheetdatei geholfen und mir folgene Variante der Pfadangabe genannt:

Code: Alles auswählen

  <metal:cssslot fill-slot="css_slot">
    <style type="text/css"
           media="all"
           tal:content="string:@import url(${context/km.css/absolute_url});"
    ></style>
  </metal:cssslot>
Ehrlich gesagt habe ich das damals einfach so hingenommen und war froh, dass es klappte. Aber ich finde es nach wie vor interssant, dass man sogar nach der eingentlichen Datei, welche eingebunden werden soll, noch die absolute_url angeben kann.
Was passiert da?

---

Mir macht die Arbeit mit Plone super Spaß Es ist einfach toll, wenn man alles so anpassen kann, wie man es will. Anderseits merke ich bei meinen ganzen Ideen, die mir durch den Kopf schwirren immer wieder, dass ich da noch mehr Know-How brauche. Und manchmal weiß ich gar nicht, ob ich die ganzen Fragen hier reinstellen soll, sofern ich es durch eigenes versuchen nicht schaffe.

---

So einen "Support" wie ich ihn sozusagen durch deine Hilfe bekomme, kann man hoch genug wertschätzen.

Ich drücke es mal anders aus:
Auch so habe ich und sicher auch viele andere hier allein durch die Fragen und Antworten von anderen Leute schon sehr viel lernen können. Hoffentlich wird sich Plone immer mehr durchsetzen.
Leider ist es heute noch sehr teuer Webspace mit Zope und Plonefunktionalität zu mieten :-(

Also dann einen schönen Tag!

Jamil
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Ich meinte natürlich, deine Hilfe kann man NICHT hoch genug wertschätzen.
Und jetzt ist mir auch wieder die eine Frage eingefallen. Vielleiht magst du sie ja in ein eigenes Thema einordnen. An einigen wenigen Stellen habe ich javascript verwendet. Allerdings ungern, da ich lieber alles in Python scripten würde.
Kann man Attribute von tags ebenso wie mit javascript durch python ändern?
Beispiel:

Code: Alles auswählen

<input  type="text"
           align="left"
           tal:attributes="tabindex tabindex/next;
           name feldname;
           id feldname;
           value python: test(DATENSATZ[feldname], DATENSATZ[feldname], request.get(feldname, ''));
           onchange="python: document.formular.lfz_muster.value = 'Beispiel'"
	                  />
Bzw. bei "onchange" ein externes Script rufen, und das object übergeben, um im Script ggf. das Attribut "value" und sonst ein Attribut zu verändern.
Interessant sind auch Attribute wie "disabled" welche Inhaltsleer sind. Setzen und entfernen per Pythonscrit. Ist das möglich?

Lieber Python als Javascript ist da meine Devise!

Grüße nochmal
Jamil
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

JR hat geschrieben:

Code: Alles auswählen

  <metal:cssslot fill-slot="css_slot">
    <style type="text/css"
           media="all"
           tal:content="string:@import url(${context/km.css/absolute_url});"
    ></style>
  </metal:cssslot>
Ehrlich gesagt habe ich das damals einfach so hingenommen und war froh, dass es klappte. Aber ich finde es nach wie vor interssant, dass man sogar nach der eingentlichen Datei, welche eingebunden werden soll, noch die absolute_url angeben kann. Was passiert da?
Hi Jamil!

Es ist einfacher zu verstehen, wenn man bedenkt, dass alles was man so an Dateien in Zope rein stellt, in Zope keine Dateien im ursprünglichen Sinn mehr sind, sondern Objekte.
Genauer gesagt, Objekte eines bestimmten Types. Und jedes Objekt erbt die Eigenschaften und Methoden von den Typen.

Alle Objekte, in denen andere Objekte abgelegt werden können, wie z.B. "Folder", erben von der Klasse **ObjectManager**.
http://localhost:8080/Control_Panel/Pro ... Manager.py

Alle Objekte, die in so einem Kontainer abgelegt sind, erben von der Klasse **ObjectManagerItem**.
http://localhost:8080/Control_Panel/Pro ... gerItem.py

Im "Online Help System" http://localhost:8080/Control_Panel/Pro ... lp/HelpSys
steht auch drinnen, von welchen Klassen das "File"-Objekt (das, glaube ich, die Basis für deine CSS-Datei war) erbt.

--> Zope Help --> API Reference --> File

class File(ObjectManagerItem, PropertyManager)

Da das File-Objekt von ObjectManagerItem erbt, erbt es auch die Methode ``absolute_url()``. Durch die Beziehung zum PropertyManager, ist es möglich, "Properties" an das Objekt zu binden.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten