James Parsons
James Parsons

Reputation: 6057

Bottle does not statics and errors correctly

I recently switched from Flask to Bottle, and I have run into a few problems.

  1. Static files are not being routed
  2. Serving error pages with @error s not working correctly

my file tree looks like:

dev
 |
 |_db
 |  |_dev.db
 |
static
 |
 |_styles
 |
 |_js
 |  |_script.js
 |
 |
views
 |
 |_index.tpl
 |
 |
 |_about.tbl
 |
 |
 |_404.tbl
 |
application.py

Here is my application.py:

# Main application file
# Created by James Parsons 2/23/15
from bottle import error
from bottle import *
from bottle.ext import sqlite

app = Bottle()
db_plugin = sqlite.Plugin(dbfile="./dev/db/dev.db")
app.install(db_plugin)

@route("/static/<filepath:path>")
def server_static(filepath):
    # FIXME Bottle is not routing statics correctly
    return static_file(filepath, root="/static/")

@error(404)
def error_404():
    # FIXME Bottle is not displaying errors correctly
    return template("404")


@app.route("/")
def index(): 
    return template("index")
    # TODO Work on index page

@app.route("/about")
def about():
    return template("about")
    # TODO Work on about page


# FUTURE Run on CGI server
run(app, host="localhost", port="80")

script.js is not available from /static/js/script.js and when I go to a nonexistent route, I do not get my custom error page, but the default 404 error. What am I doing wrong? How can I fix it?

Upvotes: 0

Views: 378

Answers (1)

Paul Rooney
Paul Rooney

Reputation: 21619

In your code you did not use the decorator methods for the app object in your static file and 404 error routes. So

@route

should be

@app.route

and the same for error.

You also probably intended to root your static files from a relative path

e.g.

return static_file(filename, root='./static/')

or

return static_file(filename, root='static/')

You were telling bottle to look in a top level directory /static/

Here is the complete code that worked for me

# Main application file

from bottle import error
from bottle import *
from bottle.ext import sqlite

app = Bottle()
#db_plugin = sqlite.Plugin(dbfile="./dev/db/dev.db")
#app.install(db_plugin)

@app.route('/static/<filename:path>')
def send_static(filename):
    return static_file(filename, root='./static/')

@app.error(404)
def error_404(error):
    return template("404")

@app.route("/")
def index(): 
    return template("index")

@app.route("/about")
def about():
    return template("about")

# FUTURE Run on CGI server
run(app, host="localhost", port="8080")

Note: I disabled the sqlite stuff as its not applicable to this question and I used the port value of 8080 to avoid needing super user rights to access the port. You should change them back when you're ready.

In the index.tpl file I referenced the js script like

<script src="static/js/script.js" ></script>

Hopefully this is enough to solve your issue.

Upvotes: 3

Related Questions