__before_publishing_traverse__ calls RESPONSE.redirect(): is there another way to change the browser URL?
Hello: I have defined a __before_publishing__traverse__() method in my Zope product. Its job is to redirect the URL displayed in the browser to a nice looking URL, something like "../myapp/invoices/123" instead of "../myapp/execute" That way all my ZPT forms can call the same method: execute(), and I don't hardcode any URLs in my ZPTs. The objective is to encapsulate my resource-to-URL mapping so that it can be changed independently from the ZPT code. I don't want to use setVirtualRoot, because I want to change the entire URL, not just "all but the leaf" The problem is that __before_publishing_traverse__ is getting called *twice* for each button press. *First* it gets called with the "../myapp/execute" URL. This is when I call RESPONSE.redirect() *Second* it gets called with the "../myapp/invoices/123" URL I am trying to understand how Zope works with the HTTP REDIRECT machinery. Is there a way to make the URL that is actually displayed in the browser *different* from the Zope method name you are calling, aside from using RESPONSE.redirect()? Thanks in advance, --Craeg Strong Ariel Partners LLC
----- Original Message ----- From: "Craeg K Strong" <cstrong@arielpartners.com> To: <zope-dev@zope.org> Sent: Monday, September 23, 2002 10:59 PM Subject: [Zope-dev] __before_publishing_traverse__ calls RESPONSE.redirect(): is there another way to change the browser URL?
Hello:
I have defined a __before_publishing__traverse__() method in my Zope product.
Its job is to redirect the URL displayed in the browser to a nice looking URL, something like
"../myapp/invoices/123"
instead of
"../myapp/execute"
__before_publishing__traverse__() doesn't affect the way the url looks to the browser. Although it can change the path being traversed inside Zope if you wish. It effectively lets any traversed object affect the rest of the traversal in some arbitrary way, or do some work before it is itself traversed.
That way all my ZPT forms can call the same method: execute(), and I don't hardcode any URLs in my ZPTs. The objective is to encapsulate my resource-to-URL mapping so that it can be changed independently from the ZPT code.
I don't want to use setVirtualRoot, because I want to change the entire URL, not just "all but the leaf"
I'm not following this.
The problem is that __before_publishing_traverse__ is getting called *twice* for each button press.
*First* it gets called with the "../myapp/execute" URL. This is when I call RESPONSE.redirect()
*Second* it gets called with the "../myapp/invoices/123" URL
I am trying to understand how Zope works with the HTTP REDIRECT machinery.
__before_publishing_traverse__ is called once for any object that defines it each time that object is traversed during a web request. A redirect generates a whole new web request, so this causes another whole set of object traversals.
Is there a way to make the URL that is actually displayed in the browser *different* from the Zope method name you are calling, aside from using RESPONSE.redirect()?
Redirect would not do this. Redirect changes the URL and makes the browser go to that URL. Whether that URL is a complete traversal to a method depends on your application. For example, a humble Python script has a traversal hook of the aforementioned variety that eats the rest of the URL path elements and binds them to the script's namespace, by default under the name "traverse_subpath". For example, given a Python script "pyscript" in your Zope root directory, then the following URL would call it: http://zopeserver/pyscript/more/path/elements When called, the script would have the traverse_subpath set to the value ['more','path','elements']. So the URL does not point to a method in this case. This is the easiest way to gather data from URL path elements. To do the same in external Python code, take a gander at the traversal hook in {Zope}/lib/python/Shared/DC/Scripts/Bindings.py which is the code that Python scripts use. hth, -Casey
Thanks for the response! I have made a bit more progress on the issue. To recap: our application consists of a number of HTML forms. When the submit button on a form is pressed, the application must do some processing in order to determine which URL should next be displayed. We are trying to follow ReST principles, so in order to view an invoice within a task order for a contract, you might view the following url http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9... We have defined a __before_publishing_traverse__ hook that determines the proper URL and then does the following: raise 'Redirect', newURL We found that by doing the redirect this way, rather than: response.redirect(newURL) __bobo_traverse__ does *not* get called. By raising an exception, the current call is aborted, and a new request is generated for the new URL. This is a good thing. However, I would like to distinguish between two cases: a) Direct Navigation: e.g.I am a user and I just typed in http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9... into my browser b) Application-Controlled: e.g. I am the application, I did some processing based on a button the user pressed in some form somewhere and determined that the next URL should be http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9... ====Now here is the issue==== In both cases above, the REQUEST object looks identical. Is there any way that I can distinguish a GET that is the result of a REDIRECT from one that is not? I would think this would be of interest to others. For example, if I move my web page and put a redirect from the old address, I could track how many people came to my web page directly versus those that are still using the old address and are getting redirected. Any advice? Thanks again! --Craeg Casey Duncan wrote:
----- Original Message ----- From: "Craeg K Strong" <cstrong@arielpartners.com> To: <zope-dev@zope.org> Sent: Monday, September 23, 2002 10:59 PM Subject: [Zope-dev] __before_publishing_traverse__ calls RESPONSE.redirect(): is there another way to change the browser URL?
Hello:
I have defined a __before_publishing__traverse__() method in my Zope
product.
Its job is to redirect the URL displayed in the browser to a nice looking URL, something like
"../myapp/invoices/123"
instead of
"../myapp/execute"
__before_publishing__traverse__() doesn't affect the way the url looks to the browser. Although it can change the path being traversed inside Zope if you wish. It effectively lets any traversed object affect the rest of the traversal in some arbitrary way, or do some work before it is itself traversed.
That way all my ZPT forms can call the same method: execute(), and I don't hardcode any URLs in my ZPTs. The objective is to encapsulate my resource-to-URL mapping so that it can be changed independently from the ZPT code.
I don't want to use setVirtualRoot, because I want to change the entire URL, not just "all but the leaf"
I'm not following this.
The problem is that __before_publishing_traverse__ is getting called
*twice*
for each button press.
*First* it gets called with the "../myapp/execute" URL. This is when I call RESPONSE.redirect()
*Second* it gets called with the "../myapp/invoices/123" URL
I am trying to understand how Zope works with the HTTP REDIRECT machinery.
__before_publishing_traverse__ is called once for any object that defines it each time that object is traversed during a web request. A redirect generates a whole new web request, so this causes another whole set of object traversals.
Is there a way to make the URL that is actually displayed in the browser *different* from the Zope method name you are calling, aside from using RESPONSE.redirect()?
Redirect would not do this. Redirect changes the URL and makes the browser go to that URL. Whether that URL is a complete traversal to a method depends on your application. For example, a humble Python script has a traversal hook of the aforementioned variety that eats the rest of the URL path elements and binds them to the script's namespace, by default under the name "traverse_subpath". For example, given a Python script "pyscript" in your Zope root directory, then the following URL would call it:
http://zopeserver/pyscript/more/path/elements
When called, the script would have the traverse_subpath set to the value ['more','path','elements']. So the URL does not point to a method in this case. This is the easiest way to gather data from URL path elements.
To do the same in external Python code, take a gander at the traversal hook in {Zope}/lib/python/Shared/DC/Scripts/Bindings.py which is the code that Python scripts use.
hth,
-Casey
Craeg K Strong <cstrong@arielpartners.com> wrote:
However, I would like to distinguish between two cases:
a) Direct Navigation: e.g.I am a user and I just typed in
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
into my browser
b) Application-Controlled: e.g. I am the application, I did some processing based on a button the user pressed in some form somewhere and determined that the next URL should be
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
====Now here is the issue====
In both cases above, the REQUEST object looks identical. Is there any way that I can distinguish a GET that is the result of a REDIRECT from one that is not?
I would think this would be of interest to others. For example, if I move my web page and put a redirect from the old address, I could track how many people came to my web page directly versus those that are still using the old address and are getting redirected.
You could try to do a POST and distinguish that from the GET when the user just types the URL. But it's probably better to add a special hidden field in your form to distinguish the two. Florent -- Florent Guillaume, Nuxeo (Paris, France) +33 1 40 33 79 87 http://nuxeo.com mailto:fg@nuxeo.com
Thanks for the advice! Unfortunately, I don't know how to do what you suggest. I believe that a redirect always causes a GET, rather than a POST, no? Also, hidden form fields are filled in on the original request, but the redirect flushes the request. All of my fields are gone! :-( Perhaps I could do something really nasty and override the Python method in urllib2 that handles HTTP redirects? Today, that code creates a new REQUEST object, throwing away the old request. I could cause it to insert some value that I would then test for, to distinguish the two cases. That would be the king of all hacks, but it might work :-} --Craeg Florent Guillaume wrote:
Craeg K Strong <cstrong@arielpartners.com> wrote:
However, I would like to distinguish between two cases:
a) Direct Navigation: e.g.I am a user and I just typed in
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
into my browser
b) Application-Controlled: e.g. I am the application, I did some processing based on a button the user pressed in some form somewhere and determined that the next URL should be
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
====Now here is the issue====
In both cases above, the REQUEST object looks identical. Is there any way that I can distinguish a GET that is the result of a REDIRECT from one that is not?
I would think this would be of interest to others. For example, if I move my web page and put a redirect from the old address, I could track how many people came to my web page directly versus those that are still using the old address and are getting redirected.
You could try to do a POST and distinguish that from the GET when the user just types the URL. But it's probably better to add a special hidden field in your form to distinguish the two.
Florent
Am Fre, 2002-09-27 um 20.58 schrieb Craeg K Strong:
Thanks for the advice!
Unfortunately, I don't know how to do what you suggest.
I believe that a redirect always causes a GET, rather than a POST, no?
Also, hidden form fields are filled in on the original request, but the redirect flushes the request. All of my fields are gone! :-(
Perhaps I could do something really nasty and override the Python method in urllib2 that handles HTTP redirects? What to hell does urllib2 have to do with Zope?
Today, that code creates a new REQUEST object, throwing away the old request. I could cause it to insert some value that I would then test for, to distinguish the two cases. REQUEST.redirect sends a status code to the browser which then requests the new URL by itself, ...
That would be the king of all hacks, but it might work :-} Probably not. The only thing you can do with redirect is to urlencode your parameters, ...
Andreas -- Andreas Kostyrka <andreas@kostyrka.priv.at>
Andreas Kostyrka wrote:
Am Fre, 2002-09-27 um 20.58 schrieb Craeg K Strong:
Thanks for the advice!
Unfortunately, I don't know how to do what you suggest.
I believe that a redirect always causes a GET, rather than a POST, no?
Also, hidden form fields are filled in on the original request, but the redirect flushes the request. All of my fields are gone! :-(
Perhaps I could do something really nasty and override the Python method in urllib2 that handles HTTP redirects?
What to hell does urllib2 have to do with Zope?
Sorry for the non-sequitur.. I do not really know if Zope uses the urllib2 machinery or not. Somewhere, however, there must be some code that catches raise 'Redirect', myurl and does the appropriate thing (creates a new request, etc.). My "find-grep" caught class HTTPRedirectHandler(BaseHandler): (line 427 of urllib2.py) But I have not looked into it enough to understand whether it is what I am guessing it is, and-- even if so-- whether Zope uses it or not. in any event, there are other, better solutions on the table, so at this point it is no longer important...
Today, that code creates a new REQUEST object, throwing away the old request. I could cause it to insert some value that I would then test for, to distinguish the two cases.
REQUEST.redirect sends a status code to the browser which then requests the new URL by itself, ...
That would be the king of all hacks, but it might work :-}
Probably not. The only thing you can do with redirect is to urlencode your parameters, ...
You're probably right. The browser is getting back a status code in the HTTP header that makes it generate a new request. The question I had was: would there be a way to stuff something in the HTTP header that the browser would somehow copy over to the new HTTP header it sends back in response to the redirect status code...? After all, it *does* copy the URL to which it is being redirected, along with all of its query parameters, etc.... A thorough re-reading of the HTTP spec would probably give me an answer... --Craeg
Andreas
Am Sam, 2002-09-28 um 05.35 schrieb Craeg K Strong:
Sorry for the non-sequitur.. I do not really know if Zope uses the urllib2 machinery or not. Somewhere, however, there must be some code that catches
raise 'Redirect', myurl Well, it's just send a response to the browser. You thing it's like this: client -> server obj -> server obj2 -> client In fact it's: client -> server obj -> client client -> server obj2 -> client
and does the appropriate thing (creates a new request, etc.).
My "find-grep" caught class HTTPRedirectHandler(BaseHandler): (line 427 of urllib2.py)
But I have not looked into it enough to understand whether it is what I am guessing it is, and-- even if so-- whether Zope uses it or not.
Nope it is not what you guess.
in any event, there are other, better solutions on the table, so at this point it is no longer important...
Today, that code creates a new REQUEST object, throwing away the old request. I could cause it to insert some value that I would then test for, to distinguish the two cases.
REQUEST.redirect sends a status code to the browser which then requests the new URL by itself, ...
That would be the king of all hacks, but it might work :-}
Probably not. The only thing you can do with redirect is to urlencode your parameters, ...
You're probably right. The browser is getting back a status code in the HTTP header that makes it generate a new request. The question I had was: would there be a way to stuff something in the HTTP header that the browser would somehow copy over to the new HTTP header it sends back in response to the redirect status code...?
Cookies (if enabled). GET style parameters appended to the URL. Problem with GET and actions is, that the HTTP spec allow the client to request it more than once. That's way at least netscape asks before rePOSTing an URL while it reloads a GET URL without user interference. Actually the HTTP spec allow an browser to get an url repeatedly for any reasons. This is the HUGE semantic difference between GET/POST. (And not that the parameters are passed via the url or stdin, ...) Andreas -- Andreas Kostyrka <andreas@kostyrka.priv.at>
Craeg K Strong wrote:
However, I would like to distinguish between two cases:
a) Direct Navigation: e.g.I am a user and I just typed in
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
into my browser
b) Application-Controlled: e.g. I am the application, I did some processing based on a button the user pressed in some form somewhere and determined that the next URL should be
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
====Now here is the issue====
In both cases above, the REQUEST object looks identical. Is there any way that I can distinguish a GET that is the result of a REDIRECT from one that is not?
I would think this would be of interest to others. For example, if I move my web page and put a redirect from the old address, I could track how many people came to my web page directly versus those that are still using the old address and are getting redirected.
raise 'Redirect', newURL+'?I_am_an_application_controlled_redirect=1' HTH, oliver
Hello: This is a good idea, and would solve the problem as stated. Unfortunately, it conflicts with my other (heretofore unstated) requirement that "all URLs shown in the browser should be bookmarkable at all times." Once a user bookmarks foo?I_am_an_application_controlled_redirect=1 and comes back to it, it is no longer telling the truth ;-) --Craeg Oliver Bleutgen wrote:
Craeg K Strong wrote:
However, I would like to distinguish between two cases:
a) Direct Navigation: e.g.I am a user and I just typed in
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
into my browser
b) Application-Controlled: e.g. I am the application, I did some processing based on a button the user pressed in some form somewhere and determined that the next URL should be
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
====Now here is the issue====
In both cases above, the REQUEST object looks identical. Is there any way that I can distinguish a GET that is the result of a REDIRECT from one that is not?
I would think this would be of interest to others. For example, if I move my web page and put a redirect from the old address, I could track how many people came to my web page directly versus those that are still using the old address and are getting redirected.
raise 'Redirect', newURL+'?I_am_an_application_controlled_redirect=1'
HTH, oliver
What you are looking for sounds like "stateful" through-the-web functionality. I think you should use sessions to remember the form fields and/or whether the user has been to this URL before. I am suspect of an app design that makes a single URL mean different things in this way, however. I suspect there is a much easier way to accomplish what you want that does not use traversal hooks or magic redirect descrimination. I'm still not sure I'm seeing the big picture of what you are really trying to accomplish here. -Casey On Friday 27 September 2002 02:53 pm, Craeg K Strong wrote:
Hello:
This is a good idea, and would solve the problem as stated.
Unfortunately, it conflicts with my other (heretofore unstated) requirement that
"all URLs shown in the browser should be bookmarkable at all times."
Once a user bookmarks foo?I_am_an_application_controlled_redirect=1 and comes back to it, it is no longer telling the truth ;-)
--Craeg
Oliver Bleutgen wrote:
Craeg K Strong wrote:
However, I would like to distinguish between two cases:
a) Direct Navigation: e.g.I am a user and I just typed in
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
into my browser
b) Application-Controlled: e.g. I am the application, I did some processing based on a button the user pressed in some form somewhere and determined that the next URL should be
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
====Now here is the issue====
In both cases above, the REQUEST object looks identical. Is there any way that I can distinguish a GET that is the result of a REDIRECT from one that is not?
I would think this would be of interest to others. For example, if I move my web page and put a redirect from the old address, I could track how many people came to my web page directly versus those that are still using the old address and are getting redirected.
raise 'Redirect', newURL+'?I_am_an_application_controlled_redirect=1'
HTH, oliver
_______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Casey Duncan wrote:
What you are looking for sounds like "stateful" through-the-web functionality.
I think you should use sessions to remember the form fields and/or whether the user has been to this URL before.
I am suspect of an app design that makes a single URL mean different things in this way, however. I suspect there is a much easier way to accomplish what you want that does not use traversal hooks or magic redirect descrimination.
I'm still not sure I'm seeing the big picture of what you are really trying to accomplish here.
-Casey
Hmm You are probably right. I confess I have not looked into the SessionDataManager stuff yet, but it looks like now would be a good time :-) I will look into it and report back.. For those who are interested, the following is a bit of elaboration on our application architecture, which will explain why my question came up in the first place. For those who are not, feel free to hit the delete button now :) Our application is a typical forms-based business app. Each page is a ZPT with one or more forms on it. Each business transaction is encapsulated by a Command (a la GOF Command pattern). That gives us "undo", logging, etc. for every command in a uniform way and separates business logic from GUI logic. Every business object is published at a unique URL. That is, a contract with ID "123" would be published at myapp/contracts/123. We use a mnemonic naming scheme: myapp/contracts/123 --> GET: get a human readable HTML read-only representation of the resource myapp/contracts/123/xml --> GET: get an XML representation of the resource myapp/contracts/123/edit --> GET: get a human readable HTML form for modifying the resource myapp/contracts/123/xml --> POST: replace the current state of the resource with the state indicated by the passed-in XML document This makes our app equally usable by humans and other apps, and also makes beautiful reports easy to build using XSLT against the xml representations. *However* we don't want to embed *any* URLs in our ZPT code. All the forms in the ZPT look like the following: <form action="." method="post"> <input type="hidden" name="stateName" value="Home"/> <input type="hidden" name="actionName" value="EditInvoice"/> <input type="hidden" name="contractId" tal:attributes="value python:contract.Id"/ <input type="submit" name="step:method" value="Edit Invoice"/> </form> There is a one-to-one relationship between ZPTs and application states. If you are in the "EditingInvoice" state, you are looking at the EditingInvoiceForm.zpt Similarly, Commands are pure-python beings. They are not allowed to know URLs. The application defines a number of states and actions in a finite state machine. The step() method asks the finite state machine for the next state given the current state and the command ("actionName" above). The application then actually executes the appropriate command, and finally executes its own internal algorithm to determine the proper URL to go to given the resulting state. For example, it knows that if the state is "EditingContract" then there must be a "contractId" in the REQUEST, and the resulting url is "contracts/" + contractId Since our business objects (like contracts and invoices) are pure-python (i.e. non-Zope objects), we do all of the traversal machinery in the __before_publishing_traverse__ and __bobo_traverse__ hooks. Some might say we pay a high price for purity :-) but it pays dividends in the robustness and ease of maintainability of the code. In many ways, we are trying to simulate a Zope-3 app on top of Zope2.5.1 Once again, thanks for all the help! --Craeg
On Friday 27 September 2002 02:53 pm, Craeg K Strong wrote:
Hello:
This is a good idea, and would solve the problem as stated.
Unfortunately, it conflicts with my other (heretofore unstated) requirement that
"all URLs shown in the browser should be bookmarkable at all times."
Once a user bookmarks foo?I_am_an_application_controlled_redirect=1 and comes back to it, it is no longer telling the truth ;-)
--Craeg
Oliver Bleutgen wrote:
Craeg K Strong wrote:
However, I would like to distinguish between two cases:
a) Direct Navigation: e.g.I am a user and I just typed in
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
into my browser
b) Application-Controlled: e.g. I am the application, I did some processing based on a button the user pressed in some form somewhere and determined that the next URL should be
http://acme.com/myapp/contracts/TRW-001/taskorders/TO-01/invoices/DSDC-001-9...
====Now here is the issue====
In both cases above, the REQUEST object looks identical. Is there any way that I can distinguish a GET that is the result of a REDIRECT from one that is not?
I would think this would be of interest to others. For example, if I move my web page and put a redirect from the old address, I could track how many people came to my web page directly versus those that are still using the old address and are getting redirected.
raise 'Redirect', newURL+'?I_am_an_application_controlled_redirect=1'
HTH, oliver
On Friday 27 September 2002 12:49 pm, Craeg K Strong wrote: [snip]
====Now here is the issue====
In both cases above, the REQUEST object looks identical. Is there any way that I can distinguish a GET that is the result of a REDIRECT from one that is not?
I would think this would be of interest to others. For example, if I move
my
web page and put a redirect from the old address, I could track how many people came to my web page directly versus those that are still using the old address and are getting redirected.
Any advice?
How about the HTTP_REFERER value? I'm not sure how a redirect affects this though. -Casey
I believe HTTP_REFERER will list the place from whence you were redirected, but unfortunately it does not distinguish between "redirect" and "following HTML link" Of which my application has many :-( --Craeg Casey Duncan wrote:
On Friday 27 September 2002 12:49 pm, Craeg K Strong wrote: [snip]
====Now here is the issue====
In both cases above, the REQUEST object looks identical. Is there any way that I can distinguish a GET that is the result of a REDIRECT from one that is not?
I would think this would be of interest to others. For example, if I move
my
web page and put a redirect from the old address, I could track how many people came to my web page directly versus those that are still using the old address and are getting redirected.
Any advice?
How about the HTTP_REFERER value? I'm not sure how a redirect affects this though.
-Casey
Craeg K Strong wrote:
I believe HTTP_REFERER will list the place from whence you were redirected, but unfortunately it does not distinguish between
"redirect" and
"following HTML link"
Of which my application has many :-(
Ok, then here are two other ideas: 1. in your redirect to an acquired method which itself redirects back to the document, this creates a HTTP_REFERER header which will tell you that it - via this method - came from your application: raise 'Redirect',newURL+'/I_am_just_here_to_show_the_special_redirect' where 'I_am_just_here_to_show_the_special_redirect' is a python script which just does context.REQUEST.RESPONSE.redirect(context.absolute_url()) I don't know ATM if you need perhaps context.aq_parent.absolute_url(). Now inspect HTTP_REFERER.split('/')[-1]. But note that HTTP_REFERER is not secure, because it's sent by the client, and some privacy tools/proxies might suppress it. 2. use cookies, which have their own problems. Or, use both methods. cheers, olive
Indeed this should work. Although I will first try out Casey's idea of using the SessionDataManager, this is a nice fallback. Very creative! :-) --Craeg Oliver Bleutgen wrote:
Craeg K Strong wrote:
I believe HTTP_REFERER will list the place from whence you were redirected, but unfortunately it does not distinguish between
"redirect" and
"following HTML link"
Of which my application has many :-(
Ok, then here are two other ideas:
1. in your redirect to an acquired method which itself redirects back to the document, this creates a HTTP_REFERER header which will tell you that it - via this method - came from your application:
raise 'Redirect',newURL+'/I_am_just_here_to_show_the_special_redirect'
where 'I_am_just_here_to_show_the_special_redirect'
is a python script which just does context.REQUEST.RESPONSE.redirect(context.absolute_url())
I don't know ATM if you need perhaps context.aq_parent.absolute_url().
Now inspect HTTP_REFERER.split('/')[-1].
But note that HTTP_REFERER is not secure, because it's sent by the client, and some privacy tools/proxies might suppress it.
2. use cookies, which have their own problems.
Or, use both methods.
cheers, olive
participants (5)
-
Andreas Kostyrka -
Casey Duncan -
Craeg K Strong -
Florent Guillaume -
Oliver Bleutgen