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.
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.
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