Probleme mit Pfad

Django, Flask, Bottle, WSGI, CGI…
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.
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hallo,

jetzt habe ich ungefähr eine halbe Stunde das Forum durchforstet und weiß immer noch nicht, ob ich quasi ohne javascript auskommen kann.

Ich bin auf folgenden Post gestoßen:

http://www.python-forum.de/topic-806.ht ... javascript

Mir geht es letztendlich darum, Fehleingaben abzufangen ohne die Seite neu aufbauen lassen zu müssen.

Zum Beispiel gibt jemand einen Wert in ein Textfeld ein und ich möchte über onchange jedesmal gucken, ob der Wert einen bestimmten String enthält. Abhängig davon schalte ich nun einen nebenliegenden Button (de-)aktiv. Geht das mit Python? Oder benötige ich für so etwas auf jedem Fall javascript?

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:Kann man Attribute von tags ebenso wie mit javascript durch python ändern? 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.
Hi Jamil!

Suche nicht weiter. Das bringt nichts. :-(

``OnChange`` und andere Actions sind alle Client-seitig und so lange der Client, also der Browser, kein Python versteht, kannst du mit Python nichts machen.

Du musst wohl JavaScript verwenden. http://de.selfhtml.org/javascript/beisp ... ngaben.htm

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

Das ist äußerst schaaaade :evil:

Mal sehen, ob sich das eines Tages ändert.
Danke für die, wenn auch enttäuschende, Antwort.

Also dann bleibts bei javascript in solchen Fällen :? .

Grüße
Jamil
Antworten