Ex50 - adding second @app.route to app.py


#1

I successfully completed ex50, and am trying out some other Flask example code.

When trying to add some Markup code, I have modified app.py to this:

from flask import Flask
from flask import render_template
from flask import Markup


app = Flask(__name__)


@app.route("/")
def index():
    greeting = "I Hope"
    qualifier = "Won't I?"
    return render_template("markup.html", greeting=greeting, qualifier=qualifier)

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

@app.route("/markup")
def markup():
    return render_template("markup.html")

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

At this point, I only see a somewhat broken version of the modified html that I borrowed from jinja’s Markup API, and not the html from /:

<html>
<head>
  <title>Do I even know how this will end up?</title>
</head>
<body>
  Markup('<strong>Hello %s!</strong>') % '<blink>hacker</blink>'
  Markup(u'<strong>Hello &lt;blink&gt;hacker&lt;/blink&gt;!</strong>')
  Markup.escape('<blink>hacker</blink>')
  Markup(u'&lt;blink&gt;hacker&lt;/blink&gt;')
  Markup('<em>Marked up</em> &raquo; HTML').striptags()
  u'Marked up \xbb HTML'
</body>
</html>

What am I doing wrong here? I had initially tried to have the app.route only set to ("/markup"), but that resulted in a Not Found error in the browser.


#2

Hmm, I have no idea. I’d look for an example of how they’re using it and then copy it. It looks like you’re calling markup at the wrong time maybe?


#3

I have a feeling it is because you are rendering the same template in two different ways, but the last one to render will be the one to render…

Here’s a simplistic way of seeing it:

#python if name == main
x = 'NONE'
def run():
  global x
  x = 'first'
  return x
  
if __name__ == '__main__':
  y = run()
  print(y)

def second_run():
  global x
  x = 'second'
  return x



if __name__ == '__main__':
  y = second_run()
  print(y)

print("global y =", y)
print("global x=", x)

except in your case, your app is your global that is being over-riden by your call to:

if name == ‘main’:
both routes are being called. But the last one will be the one that is final render.

Just my theory. Try taking the first < name == ‘main’> out.


#4

You’re right that when I remove the first name==main, “/markup” is the only template that loads. Looking closer, that’s because of this line under @app.route("/"):

return render_template("markup.html", greeting=greeting, qualifier=qualifier)

When I change “markup.html” to “index.html” or “datetime.html”, it loads those templates instead.

Using a very simplified version of a second app.route:

from flask import Flask
from flask import render_template

app = Flask(__name__)

@app.route("/")
def index():
    greeting = "I Hope"
    qualifier = "Won't I?"
    return render_template("foo.html", greeting=greeting, qualifier=qualifier)

@app.route('/test')
def testing():
    return 'test'

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

I just need to change the localhost URL to http://127.0.0.1:5000/test and I can get the second @app.route. Success! Kind of. Attempting the Custom Tests from the Flask/Jinja docs, I’m unable to get /math to run because the variables aren’t recognized.

@app.route("/math")
def is_prime(n):
    environment.tests['prime'] = is_prime

    if n == 2:
        return True
    for i in xrange(2, int(math.ceil(math.sqrt(n))) + 1):
        if n % i == 0:
            return False
    return True