After reconsidering the whole thing, I've found a way to achieve what I 
wanted, without having to change too much code.

Considering that I needed to keep client-side caching, the only way to go 
was redirecting the user to a "different URL".
So I used a lazy argument: when the user logs in, he is redirected to the 
previous URL where he was, but with a lazy argument at the end of the URL. 
This way, the browser sees a different URL, and it doesn't use the local 
cache.

Because of the "log in" link is in every page of the template, I had to 
consider the args and vars that could already be in the current path.
So, in the template the login link is created like this:

{{
_args = request.args
if 'l' not in _args:
    _args.append('l')
pass
login_url = URL('default', 'user', args='login', vars={'_next':URL(args=
_args, vars=request.get_vars)})
}}
<a href="{{=login_url}}">Log in</a>

Then of course, the function in charge of logging in the user redirects him 
to the URL received in request.vars._next

In my models:

# Setup cache.action arguments
CACHE.time_expire = 300
CACHE.public = True
CACHE.session = False
CACHE.vars = False

# if the user is logged in, setup different cache.action arguments
if auth.is_logged_in():
    CACHE.prefix = 'plantel-'
    CACHE.time_expire = 1
    CACHE.model = None

This way is working like a charm, and I was able to save an additional 
extra request just to load a topnavbar.
Although, this is not bullet proof: the user may still clic a link to a 
page that is in his local cache, so there is no way to avoid that.
For this case and what I needed, the solution is acceptable.


As always, thankyou very much Niphlod for your time.
I wanted to post my solution just in case someone needs to deal with a 
similar situation.

Regards, Lisandro.



El lunes, 6 de junio de 2016, 19:01:27 (UTC-3), Niphlod escribió:
>
> it's kinda chicken-and-egg here, because your real trouble is that the 
> unlogged user hits a page that you want to be cached client-side as long as 
> he is not logged in.
> if you let it cache client-side, having the user returning to the same 
> page to expect a different outcome is impossible. 
> IMHO the solution is that you should refactor your app to present a proper 
> "landing page" uri for public viewers and a separate one for logged in 
> users. 
>
> On Monday, June 6, 2016 at 7:10:51 PM UTC+2, Lisandro wrote:
>>
>> I've been doing some more test and a bit more reading about this, and I 
>> can see (if I'm not wrong) that this is not a problem, it's the expected 
>> behaviour.
>> @cache.action does precisely that: it sets cache headers for client-side 
>> caching, that is, browser side caching. 
>> And, *optionally*, it allows you to set server-cache also (using a 
>> cache.model, like ram, disk or redis).
>>
>> So, using @cache.action, the user (without being logged) visits a page 
>> and the browser stores the view in cache. 
>> Then the user logs in, and returns to the previously visited page, and 
>> the browser uses the copy in local caché.
>>
>> I've read that I could use the old (but still perfectly valid) method of 
>> @cache decorator.
>> However @cache.action has some facilities to handle vars and session. 
>> wich aren't present with @cache
>>
>>
>> The whole point of this was to avoid an extra ajax call from the views.
>> I was using the same cached view for all users, and the HTML returned to 
>> the browser had an ajax call that loaded the user menu. 
>> However. this meant that the models were executed twice per every page 
>> visit, and that wasn't very good, also I'm trying to save CPU.
>>
>> I'll try to figure out if there is an alternative.
>>
>>
>>
>> El lunes, 6 de junio de 2016, 10:26:35 (UTC-3), Lisandro escribió:
>>>
>>> I need to decorate a controller function with @cache.action in order to 
>>> have two different versions of the rendered view: one for logged-in users 
>>> and another one for not logged-in users.
>>>
>>> Notice that I don't need one different caché for each user (that could 
>>> be achieved using session argument). 
>>> Instead, what I need is two versions of the rendered view: one for all 
>>> the users that aren't logged-in, and one for all the users that are 
>>> logged-in.
>>> The only difference between those two versions of the rendered view is 
>>> that one of them includes a top navbar, which is is the same for all 
>>> logged-in users, but it shouldn't be present in the cache version for not 
>>> logged-in users.
>>>
>>>
>>> Because I need the same behaviour in several controller functions, the 
>>> way I do it is defining the @cache.action parameters at the models level, 
>>> like this:
>>>
>>> CACHE = Storage()
>>> CACHE.prefix = ''
>>> CACHE.time_expire = 300
>>> CACHE.public = True
>>> CACHE.session = False
>>> CACHE.vars = False
>>> if auth.is_logged_in():
>>>     CACHE.prefix += 'logged-in-'
>>>     CACHE.public = False
>>>     # CACHE.model = None
>>>
>>>
>>> The I use that configuration in controller functions:
>>>
>>> @cache.action(time_expire=CACHE.time_expire, cache_model=CACHE.model, 
>>> session=CACHE.session, vars=CACHE.vars, public=CACHE.public, prefix=
>>> CACHE.prefix)
>>> def index():
>>>     return response.render(...)
>>>
>>>
>>> @cache.action(time_expire=CACHE.time_expire, cache_model=CACHE.model, 
>>> session=CACHE.session, vars=CACHE.vars, public=CACHE.public, prefix=
>>> CACHE.prefix)
>>> def forum():
>>>     return response.render(...)
>>>
>>>
>>>
>>> However, I'm having trouble to make it work as I want. 
>>> It's not working entirely wrong, but the problem is this:
>>>   1) the user hits the index, without being logged-in;
>>>   2) the user logs in
>>>   3) the user goes back to index, but still sees the cached page (I 
>>> think it's the browser that is using local cache). If the user reloads the 
>>> page (hitting F5 or Ctrl+R), then the new view is shown.
>>>
>>>
>>> What am I missing?
>>>
>>> As you can see in the code, I've tried:
>>>  - setting public=False regardless of the logged in state;
>>>  - setting cache.model=None when the user is logged-in;
>>>  - using a different prefix for logged in users;
>>>
>>> But the problem remains: after logging in, the user need to hit F5 in 
>>> order to see the other view.
>>>
>>>
>>> As always, I will appreciate any help on this.
>>> Regards, Lisandro
>>>
>>

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to