edmondchuc / flask-htmx

A Flask extension to work with HTMX.
http://flask-htmx.readthedocs.io
MIT License
132 stars 15 forks source link

Issue with if htmx statement when using init_app #25

Closed 78wesley closed 1 year ago

78wesley commented 1 year ago

Hi, I am trying to use init_app with htmx. But I can't get it working. For some reason the if htmx: statement doesn't work as it needs to be. when I go to the direct link /bigdata it still shows the data. It should only show the data when I go the the index page.

app.py

from flasktest import create_app

app = create_app()

if __name__ == "__main__":
    app.run(debug=True)

flasktest/__init__.py

from flask import Flask
from flask_htmx import HTMX

def create_app():
    app = Flask(__name__)
    app.config['SECRET_KEY'] = "secret"

    htmx = HTMX()
    htmx.init_app(app=app)

    from flasktest.routes import bp as routes_bp
    app.register_blueprint(routes_bp, url_prefix="/")

    return app

flasktest/routes.py

from flask import render_template, Blueprint
from flask_htmx import htmx

bp = Blueprint('main', __name__)
bigdata = ["somedata"]

@bp.route('/', methods=['GET', 'POST'])
def index():
    bigdata.append("somemore")
    return render_template('index.html', bigdata=bigdata)

@bp.route("/bigdata", methods=['GET'])
def bigdata_func():
    if htmx:
        return render_template('bigdata.j2', bigdata=bigdata)
    return "This needs to be a bank page!"

flasktest/templates/index.html

<!DOCTYPE html>
<html>

<head>
    <title>BIG DATA</title>
    <script src="https://unpkg.com/htmx.org@1.9.4" integrity="sha384-zUfuhFKKZCbHTY6aRR46gxiqszMk5tcHjsVFxnUo8VMus4kHGVdIYVbOYYNlKmHV" crossorigin="anonymous"></script>
</head>

<body>
    <h1>here should be test data</h1>
    <div hx-get="/bigdata" hx-trigger="load" hx-swap="outerHTML"></div>
</body>

</html>

flasktest/templates/bigdata.j2

<ul>
    {% for x in bigdata %}
    <li>
        {{ x }}<br>
    </li>
    {% endfor %}
</ul>
78wesley commented 1 year ago

If I don't use the init_app like if I do everything in one file. it does work.

app2.py

from flask import render_template, Flask
from flask_htmx import HTMX

app = Flask(__name__, template_folder="flasktest/templates")
app.config['SECRET_KEY'] = "secret"

htmx = HTMX()
htmx.init_app(app=app)

bigdata = ["somedata"]

@app.route('/', methods=['GET', 'POST'])
def index():
    bigdata.append("somemore")
    return render_template('index.html', bigdata=bigdata)

@app.route("/bigdata", methods=['GET'])
def bigdata_func():
    if htmx:
        return render_template('bigdata.j2', bigdata=bigdata)
    return "This needs to be a bank page!"

if __name__ == "__main__":
    app.run(debug=True)
78wesley commented 1 year ago

I've found the solution on the flask website at the section The Extension Class and Initialization at the second code demo.

I needed to move the line htmx = HTMX() outside of the function create_app() and change the import at flasktest/routes.py from from flask_htmx import htmx to from flasktest import htmx.

flasktest/__init__.py

from flask import Flask
from flask_htmx import HTMX

htmx = HTMX()

def create_app():
    app = Flask(__name__)
    app.config['SECRET_KEY'] = "secret"

    htmx.init_app(app=app)

    from flasktest.routes import bp as routes_bp
    app.register_blueprint(routes_bp, url_prefix="/")

    return app

flasktest/routes.py

from flask import render_template, Blueprint
from flasktest import htmx

bp = Blueprint('main', __name__)
bigdata = ["somedata"]

@bp.route('/', methods=['GET', 'POST'])
def index():
    bigdata.append("somemore")
    return render_template('index.html', bigdata=bigdata)

@bp.route("/bigdata", methods=['GET'])
def bigdata_func():
    if htmx:
        return render_template('bigdata.j2', bigdata=bigdata)
    return "This needs to be a bank page!"