Задать вопрос

Тел: +7 965 3737 888





Extended rails flash implementation

<p>This is an extendend version of the Rails Flash implementation by Sean Patrick Hogan that supports different message types.</p>
<p><strong>Setting a flash message:</strong></p>
request.flash.error = 'Item could not be saved'

request.flash['error'] = 'Item could not be saved'

request.flash['foo'] = 'bar'

<p><strong>Displaying a flash in the view:</strong></p>
&lt;!-- show the error message --&gt;
{% if flash.error %}An error occured:{{ flash.error }}{% endif %}

&lt;!-- just show the first message found --&gt;
{% if flash %}An error occured:{{ flash }}{% endif %}

&lt;!-- show all messages --&gt;
{% for msg in flash %}{{ msg.type }}: {{ msg.msg }}{% endfor %}

<p>Note that it still works with simple strings as well. Feel free to just use it like this:</p>
request.flash = "Message"

{% if flash %}{{ flash }}{% endif %}

<p>However, be aware that once you did this, you destroyed the Flash() dict and thus lost the extended functionality.</p>
<p>You can use request.flash.clear() to remove all messages.</p>

Вопрос полезен? Да0/Нет0

Ответы (7):

Ответ полезен? Да0/Нет0

thanx for this RoR borrowing, pretty interesting

Ответ полезен? Да0/Нет0

ChloeO, put it in the same file as "class Middleware". As a matter of fact, you can put everything in one file (this is how I do it).

Ответ полезен? Да0/Нет0

Hello, this probably is a dumb question, but where do i put class Flash(dict)? Thanks!

Ответ полезен? Да0/Нет0

Rails works by doing:

flash.now[:notice] = 'Message'

Basically, it (this snippet) doesn't work (for this case) because the response is being processed after the view is. So, you've done your view and Django has the page rendered and it is at that point, right before sending it to the browser, that it calls process_response. So, there is nothing in the session's flash when the context processor is being called unless you've redirected.

But this can be fixed (and rather easily). Since we aren't redirecting in this scenario, we don't even have to bother storing it at all! Everything is resident in memory for the entire time we need it!

So, if we do something like:

request.flash['now'] = 'Heya!'

we have something that differentiates it - a "now" case.

Now, the context processor can say: hi! Is there a flash in this user's session? If so, I want to display it. Well, maybe there's a "now" flash that is in the request object itself that I want to display if there is no session flash.

That would look like this context processor:

if 'flash' in request.session:
    flash = request.session['flash']
    del request.session['flash']
    return {'flash': flash}
elif 'now' in request.flash:
    flash = request.flash['now']
    del request.flash['now']
    return {'flash': flash}
return {'flash': None}

What we've done is look to see if there is a session flash. Ok, there isn't. Then we look to see if there is a "now" flash. Yes! So, just put that in the view and delete it so that the process_response doesn't add it to the session for the next pageview.

Anyway, just ping me if this needs clarification.

Ответ полезен? Да0/Нет0

Hm, that should read "How does Rails work in that regard" - just were are my glasses? ;)

Ответ полезен? Да0/Нет0


you're right - I never used it that way? How does Rails even work win that regard?

Anyway, I am not 100% sure of the implication or possible side effects of this, but I think it should work just fine. Try this context processor instead:

def context_processor(request):
    # start with flash from current request and reset it (so it won't
    # be stored in the session)    
    flash = request.flash
    request.flash = Flash()
    # add flash from session (e.g. from before a redirect), if any
    if 'flash' in request.session:        
        del request.session['flash']
    # make available in template
    return {'flash': flash}

Ответ полезен? Да0/Нет0


I just found an issue. It doesn't work unless I redirect the user after I set the flash message. In other works it seems that the session value that is set is not accessible in the same request. For example: if a user submits a form and I want to display a flash message it doesn't get displayed unless I refresh the browser.

Any thoughts?


Sebastian Macias