web-dev-qa-db-ja.com

Flask flashを使用してリンク付きのメッセージをフラッシュする方法は?

Flaskを使用してGoogleOpenIDを処理するWebアプリを作成しています。点滅するメッセージにリンクが含まれていることを除いて、これらのコードはほぼ完成しています。

@oid.after_login
def create_or_login(resp):
    user = db_session.query(User).filter_by(email=resp.email).first()
    if user is not None:
        flash('Successfully signed in', 'success')
    else:
        user = User(nickname=resp.fullname, source=GOOGLE, email=resp.email)
        db_session.add(user)
        db_session.commit()
        flash(flashing_message, 'success')
    g.user = user
    session['nickname'] = user.nickname
    return redirect(oid.get_next_url())

Flashing_messageが次のような場合にうまく機能します:'Successfully registered, please click here'

ただし、flashing_messageが'Successfully registered, please click <a href="/me" class="alert-link">here</a>'の場合、エラーをスローせずに機能しません(何もフラッシュしません)。不思議なことに、flash()とreturnの間の文も機能しません(session ['nickname]またはg.userを設定しませんでした)。

13
kxxoling

ここでの他の答えは、すべてのフラッシュメッセージが安全であるとマークされるようにテンプレートを変更することに焦点を当てていますが、これはあなたが望むものではないかもしれません。

特定のフラッシュされたメッセージを安全としてマークしたいだけの場合は、flash()に渡されたテキストをMarkup()でラップします。 ( マークアップ用のFlask APIドキュメント

たとえば、次の代わりに:

flash('Successfully registered, please click <a href="/me" class="alert-link">here</a>')

次のようにMarkup()で文字列をラップします。

flash(Markup('Successfully registered, please click <a href="/me" class="alert-link">here</a>'))

いつものように、flaskパッケージから次のようなマークアップをインポートする必要があります:

from flask import Markup
28
Pete Watts

flash()を呼び出した後、テンプレートをレンダリングする必要があります。これにより、get_flashed_messages()を使用してメッセージが取得されます。 flash()を呼び出した後にテンプレートを呼び出すようにコードを調整する必要があります。 flashは、テンプレートによって抽出できる次の要求にメッセージを送信します。テンプレートは次のようになります。

{% with messages = get_flashed_messages() %}
    {% if messages %}
    <ul class=flashes>
    {% for message in messages %}
        <li>{{ message | safe }}</li>
    {% endfor %}
    </ul>
  {% endif %}
{% endwith %}

ビューコードでは、flash()呼び出しの直後にrender_templateを追加します。何かのようなもの:

flash('success')
return render_template('whatever.html')   
3
codegeek

HTMLのエスケープはデフォルトの動作であるため、safeフィルターを通過させて、エスケープされていないHTMLを表示します。

{{ message|safe }}
1
Blender

正しいかどうかはわかりませんが、これを解決する方法は、HTMLの文字列である関数内の別の変数を宣言し、それをrender_template()関数に渡すことでした。

そして、テンプレートでそれをsafeフィルターに通しました。

たとえば、(おおまかに基づいて)提供したコードは次のとおりです。

_@oid.after_login
def create_or_login(resp):
    user = db_session.query(User).filter_by(email=resp.email).first()
    if user is not None:
        flash('Successfully signed in', 'success')
    else:
        user = User(nickname=resp.fullname, source=GOOGLE, email=resp.email)
        db_session.add(user)
        db_session.commit()
        flash(flashing_message, 'success')
        link = "<a href=\"some_link.html\">Link</a>" ## ADDED HTML WITH LINK ##
    g.user = user
    session['nickname'] = user.nickname
    return render_template('some_layout.html',
                           link=link  ## PASS THE LINK TO THE TEMPLATE ##
    )
_

次に、テンプレートで、get_flashed_messages()if内に追加のifステートメントを追加しました。

_{% with messages = get_flashed_messages(with_categories=true) %}
    {% if messages %}

    ... Code that was already here ...

    {% if link %}        ## PASSED THE LINK TO THE TEMPLATE HERE ##
      {{ link | safe }}
    {% endif %}

    {% endif %}
{% endwith %}
_
0
m__