I'm grappling with the idea of having "virtual folders" (for want of a better term) existing under a Zope folder and am not sure how to implement it. The user will basically be navigating through subobjects whose identity will be stored in a database: http://somehost/notes/a/b/c where a, b, c correspond to some structure in the database. My question is it possible for the object at http://somehost/notes to handle all requests to subobjects under it without creating them by hand in Zope? I suspect some Python programming would be involved but I'm not sure what. Tim. -- Tim Potter, System Admin/Programmer "Disco Stu doesn't advertise" Advanced Computational Systems CRC, RSISE Bldg Australian National University, Canberra 0200, AUSTRALIA Ph: +61 2 62798813 Fax: +61 2 62798602
At 12:54 PM 8/6/99 +1000, Tim Potter wrote:
I'm grappling with the idea of having "virtual folders" (for want of a better term) existing under a Zope folder and am not sure how to implement it. The user will basically be navigating through subobjects whose identity will be stored in a database:
where a, b, c correspond to some structure in the database. My question is it possible for the object at http://somehost/notes to handle all requests to subobjects under it without creating them by hand in Zope? I suspect some Python programming would be involved but I'm not sure what.
I'm pretty sure this is documented somewhere, I'm just not sure where, so here goes. The Zope ORB will publish sub-objects by using getattr and getitem by default, but you can control its traversal process manually with the __bobo_traverse__ hook. If an object defines a __bobo_traverse__ method, then that is called to traverse the object. __bobo_traverse__ is called with two arguments, the REQUEST and the entry name or URL fragment. The method should return a subobject named by the entry name or None. You can also return a tuple of objects indicating that they are all traversed (this is a way to sneak extra objects in the PARENTS list). So in your example you want to write an object that will gobble up all the entry names that follow it. Here's how that could be done, def __bobo_traverse__(self, REQUEST, name): "I am my own sub-object" return self I think I learned this trick from Phillip Eby, but I can't remember ;-) Later you can consult the REQUEST to determine what the path info was. Actually, now that I think of it you'll need something a little more complex, since you need to actually publish something in the end. ZPublisher will try for the 'index_html' method, but that's just more of the same, so you can either explicitly do some testing in __bobo_traverse__ to return 'index_html' when asked, or you can rely on __call__. Here's a minimally working example, class PathEater: "Eats path info for breakfast" def __init__(self): self.steps=[] def __bobo_traverse__(self, request, name): self.steps.append(name) return self def __call__(self): "Publish method" return "I ate %s" % self.steps If you want to experiment with stuff like this I highly recommend using ZPublisher.Test and ignoring the Zope framework until you understand object publishing on a more basic Pythonic level. Good luck! -Amos
On Thu, Aug 05, 1999 at 11:42:21PM -0700, Amos Latteier wrote:
At 12:54 PM 8/6/99 +1000, Tim Potter wrote:
I'm grappling with the idea of having "virtual folders" (for want of a better term) existing under a Zope folder and am not sure how to implement it. The user will basically be navigating through subobjects whose identity will be stored in a database:
where a, b, c correspond to some structure in the database. My question is it possible for the object at http://somehost/notes to handle all requests to subobjects under it without creating them by hand in Zope? I suspect some Python programming would be involved but I'm not sure what.
I'm pretty sure this is documented somewhere, I'm just not sure where, so here goes.
<SNIPPED deep Python/ZopeZen discussion by Amos>
If you want to experiment with stuff like this I highly recommend using ZPublisher.Test and ignoring the Zope framework until you understand object publishing on a more basic Pythonic level.
Tim - if you don't want to get into the python right away, it sounds like you mightr be able to use Direct Traversal of ZSQL objects. Where's that doc - ah, here it is. My ZSQL user's guide has it on page 11, under 'Object Access' give this example: http://plutonia.com/Plutonia/Computer/lookup_part/part_number/fdax/orders where lookup_part is a ZSQL method that takes part_number as a parameter, 'fdax' is the value it will be called with in this URL, and the result object will be rendered with the 'orders' method. Pluggable brains get into the act somewhere between my example an Amos's, I think. (Some times, I'd like to plug in an upgraded, more ZopeZenCompatible(tm) brain for myself!) HTH, Ross -- Ross J. Reedstrom, Ph.D., <reedstrm@rice.edu> NSBRI Research Scientist/Programmer Computer and Information Technology Institute Rice University, 6100 S. Main St., Houston, TX 77005
At 11:42 PM 8/5/99 -0700, Amos Latteier wrote:
Later you can consult the REQUEST to determine what the path info was.
Actually, now that I think of it you'll need something a little more complex, since you need to actually publish something in the end. ZPublisher will try for the 'index_html' method, but that's just more of the same, so you can either explicitly do some testing in __bobo_traverse__ to return 'index_html' when asked, or you can rely on __call__.
Here's a minimally working example,
class PathEater: "Eats path info for breakfast"
def __init__(self): self.steps=[]
def __bobo_traverse__(self, request, name): self.steps.append(name) return self
def __call__(self): "Publish method" return "I ate %s" % self.steps
If you want to experiment with stuff like this I highly recommend using ZPublisher.Test and ignoring the Zope framework until you understand object publishing on a more basic Pythonic level.
By the way, speaking of the Zope framework... If you're going to do something like the above in Zope, keep in mind that this will do terrible horrible nasty things unless you name the steps attribute _v_steps so that it doesn't get stored in the object database. Otherwise every hit to a PathEater will create worthless transactions modifying the 'steps' attribute on disk. Ugh!
So in your example you want to write an object that will gobble up all the entry names that follow it. Here's how that could be done,
def __bobo_traverse__(self, REQUEST, name): "I am my own sub-object" return self
I think I learned this trick from Phillip Eby, but I can't remember ;-)
Well, *I* got it from Jim Fulton, so there. :)
On 6 Aug 1999 02:20:00 -0500, Amos Latteier wrote:
At 12:54 PM 8/6/99 +1000, Tim Potter wrote:
I'm grappling with the idea of having "virtual folders" (for want of a
The Zope ORB will publish sub-objects by using getattr and getitem by default, but you can control its traversal process manually with the __bobo_traverse__ hook.
I am currently developing a product which publishes objects based on information stored in filesystems. It creates two classes of folderish objects, an extended 'Directory Folder' and a 'Database Folder'. The Directory folder is simply a Zope Folder class which attempts to locate interesting objects and attributes contained within the filesystem subdirectory (recursively). It instantiates a Directory Folder in the Zope database for each subdirectory it encounters as it walks the specified directory tree. The folder instantiation is done to allow one to place other Zope components in each folder. The Database Folder is a virtual object instantiated in the Zope database as a folderish object which knows how to locate and make available application-specific 'database tables', CSV tables, HTML/DTML files which are treated as instance methods and which are not instantiated in the Zope database, but are entirely virtual objects. Also instantiated in the Zope database in order to allow other Zope components. The database and CSV table handling is done by a new set of TinyTables Classes which Ty wrote to implement the Data Mining capabilities posted about a month or so ago. The new Table Mining Class implements a subMine class which is instantiated each time a Table is 'mined' and is managed by URL component. So there's a lot of virtual stuff going on here. We make extensive use of __bobo_traverse__ and __getattr__ in all of this stuff to either try to watch for changes in the filesystem objects or to navigate virtual methods and objects. For the most part, it works great. However, as I mentioned in Zope.dev, I've having a little bit of trouble with __bobo_traverse retaining variable values from one call (GET) to the next. I have included a Test Folder object which shows the problems and possibly shows what I need to have saved (it does not implement the directory class stuff). I need the bobo_traverse (or something like it) that allows me to automatically check the status of objects before they are rendered. Bobo_traverse does exactly what I need, with the exception that I need '_v_variable' value changes to be retained during the zope session. Sure would appreciate some helpful suggestions. If I could figure out how to deal with this problem, I could release an example virtual folder filesystem-mapping product for you guys to play with. Thanks Kent begin 644 Test.tgz M'XL("+D!JS<``U1E<W0N=&%R`.U8:V_B2!;-U_A77)&)@!X:2#H$#0J1D@Y) MT"2!!?=H9Q^R#"Y";?Q`KG((6LU_WWO+96SS2%H]V>Z5EOH`=KGJW/>IA\M' MM=E"3@._U@\#)QI+43.9D+6]]VMP4F\VF[`'U.HK__H%3IN-X]-Z_;3Q">#H MI%YO[D'C'778VB(A[1!@+PP"^=JX^90Q]WLH]'V;NRW^]%.=+=Y#QA%&L]&@ M>!_7ZR=K\6\VFD=Q_!O-!H8>X]\X:9SL0?T]A+_5DO@_,?__,?X'Q@%0J.$Z M<!T6@DX"@_I_19=`/W"?/L+P^G*@^KC_C*/YHRT9S*<+>+9#;H]<A@]NQ`0( M)G$,V&!9HV`46#*TGUDHF&7!V'9=1'`"\`,),^SE*'<2!AX$/H-;T^S#3<<$ M&8"<,O#9BZPJF5V8!Y'K@#V;A6S,2?23'\RY_ZA4D%,N(!B/HU"`[3LP#>:$ M\8B:)-HAR-OZX9PUI4AGK1!BI"H]!*B$G-I2J9I#`H]A.3DPYSC5EI)Y,TD0 MP8SY2C\T@_D.><*6=F+MA*,/BS7IS6H2'3Q1T7"#QR+*`S`,RW*"L66UB\7B M%4<OR"!<9`.'_32(-."!3P-_&K!G3B\MJ%?K=?BI^/>CH];'XW\:AC+OQ@U& MMBN`>[,@E.C^^[MK5*("]TP(^Y%=<1OE5Z`?^P1S(9[7NQY6=;+HJ?%;_/4J M&$<>CC71;)<BE8$W#(=-P!E%CZ67<LN@VI]`6SFFM,GT"A3M8CD>5YV'7#*< MIU_';B!8J6P8MN-TT<?70>BU$QM*Q0O'(>=HWU3@,3:V5"XK'?2DDF#NI`+< MJ8#DTF7HW0H,.G_YTAF:[0>,O]:R4"@@("9-ME(P<#;$RN)W0PTDO*J%.=8; M_0MC5"+D5(_24A"JH<;S22(.,(>I+$AJR]@/F8Q"/\;S;!_#87DV]V.%]91* M-,,,P@_,C]I'B#AV;2&R\N*_U(B,^J0R]6*RVI9<S!@&HIC-IUA!<I9E<9]+ MRUKUEL9=VLT=Q.!.OE.-Q'[U;QC[R#93)EC*&V*J:CMD@CN,2C,IJ)$MF+$? M@Z!>:7VUH9[M5R5*?=O!R;&O"K">K6TRDD\Y,<-HA"0H(R*!9,HD"(ES,$L] M5>XCP<)G!@Z?3%A(3#IB4_N9!Z'(>':%@[2+DP##$ULD>7B03M)2EL,SHQ+? M8WB7BG$?U4G5>.9LCGPY47X@"EIF+[4#^`V=IWS'I$2*%0EAV^[<7HA7*5(1 M)/EGSN44\L95,3:8XY[]1"P<A2E]+H"](&(5)W[\D\W8QXHB9:>V0.H-M8.* MJ_$MHJOVTX+=&/W7D<CJS2C+1'D'<XQ]Q9;%?_C(@_IY?>'"^+?@4%!NTZ_3 M.A0X(5;ML"10>1Q1KH#09F0>L6C+Y25T;(?E\#&6.RA,!44H\>#,S&0<S:>8 M/S`,.O+BAZ4;EV6(<4="0_YB3IHW^453;0X0)9-(\(&]C-E,?H#()\(5@8>K MTP(7<'J?*+1QX#M<XB(G<"O`QU/$\8LJ!4<,9;HD?X$/XY`A53JJ2(6,G$45 MNG$%("]$KL3I6!TJX(*KO"=O>@M"PJ5HHA9&6LR%^J92%[<<R+<H&U5?*"R] MQ[!#MFXO(:V62@66>QL1B1FN&+BDS,(`?>;%->0M-)'8RLAJ$BGNHT6TSI(V MAZ(%^0160@\=DI4/WAJ;4O`W<NR&SI^/$O&'CLJ*#7#&5@W7JNQ5)5='+_7< M4*R;^S=KNX:[5!B3/:U?S'UG-?%S*TY:-#@O5_K;IF8'J9+1:SRR>89@J%+3 MI9=CHK]84^FY^95A`]W'[!IO/5%"@!Q/:48BTT),M[B*]/^7V!+=2=MAW(50 MEY5:KCDM9:(M++8$4'\_P[>RF2*S5#?TJE[YEAG-G.J:L,T%J1#>+D:5$AOV M-"L=*J/S8M<*4?$H69!S,!V0?"2IC`FT]R2^9O'.4T<E1\JE\E?8F9/S526= MM78E#=;[WK`Y.]98'RG666>]/+<02WDCWEM@FR@VK74ZH)0(K6S\Z(._;EOO M?Y)=_SO<`;UQ_W-TTM#W/R?UYLEI`WM.CT^;N_N?[]&R%PO?>IUPL*U!5QW^ MD6SN,;5<W!IM'6H8^J*`E'@-\AZ72U6/KT#A9M3VF#KD!.H@+NC$CVJ,]&W1 M+$[UEK$\_@HL\Y):3_^=KJH^HA1:\7/V[%R!7%/'3J#!R;$JE@H$G*+98]K# M*;R"/M/;V6L*NL)`Z!A-K^1TR>`XM'^L*A"%]D?%*).1%[C2\A$>0@64(A&I M;6@AGB@*99J+F^#8<'R.KRH$/8IH1KY&"+4O)BK7?E(>H?GHCM@1VU5%0]0E M<>8&IK)]BO9C;DK%^(/LZ+/0XVHGO47G%J:B/;9FRW$"%_0D7NBOV$ET)A;Q MGJBD[FLR(1.%BO[PBN<WZUTN*W?_Z$+]+[6M_)^[0:LZN!'[9AEO\?^GTV;, M_Y\^G3:.Z?Z?GG?\_SW:&6U)SHVSV\[%%?Z97?.N<[Y2/&>UN-LXJ^EAE[VK MW^'RYG/OKC=H%PZN52O`7??A5WRM8_OEEP+\IM\;JA5(RO$Z-O89QEG_W+A( M;E;ID)Z<M+F/\?''V3N]^%YJ>9U61;7Z&H*8$V=[^!%/0,DY:!%$1";Q'4#^ M%K>*\ZY[@WNX^&QV>P_MS10`]QWSMG?5+O1[0Y/L,"\N[SKPN7-W-^Q??.X^ MW+0+QZI_<(XT<V9>P<5=]P;A[CK7)CI"OYF]?D$-&)J#WL/->=<YJ^E'ZJV9 M5U\WO?O0_V*"^7N_@YV=O^*0AXM[?.9.`8;=O^'325U-^X*/A10;?P<9+6_? M$-.Y/S?IVO:LAD\QR.V?4U#=`F=TW*@:PI_K3O5S.3C/`0Z_7-YWS:5]0!E5 M4`@I3DU%B!XHNO1/*:LR6.7[CRZ[7=NU7=NU7=NU7=NU'];^`R5<<7``*``` ` end
participants (5)
-
Amos Latteier -
kent@tiamat.goathill.org -
Phillip J. Eby -
Ross J. Reedstrom -
Tim Potter