Getting Started with Bottle

I had a little trouble getting started with Bottle. The main thing was that I had trouble accessing my own Javascript in Bottle’s BasicTemplates. The trick was to do two things:

  1. Allow templates to access the “get_url” function
  2. Create an endpoint to serve your own static pages yourself

Here is my file structure:

simple-server
  venv
    ...
  static
    js
      handlers.js
  templates
    base.tpl
    index.tpl
  app.py

First, app.py is simple. Line 9 defines a route for static files, line 14 is my main page, and line 19 provides some data that we will serve dynamically on the main page.

# app.py
import bottle
from bottle import run, template, static_file

app = bottle.default_app()
bottle.BaseTemplate.defaults['get_url'] = app.get_url


@app.route('/static/:path#.+#', name='static')
def static(path):
    return static_file(path, root='static')


@app.route('/')
def index():
    return template('templates/index.tpl')


@app.get('/data')
def get_vin():
    return 'DEADBEEFDEADBEEF'


run(host='localhost', port=8080)

The base template imports bootstrap, jquery, and my own javascript.

<!DOCTYPE html>
<html>
  <head>
  	<title>
  	  {{title or 'No Title'}}
  	</title>
  	<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js" integrity="sha384-u/bQvRA/1bobcXlcEYpsEdFVK/vJs3+T+nXLsBYJthmdBuavHvAW6UsmqO2Gd/F9" crossorigin="anonymous"></script>
    <script   src="https://code.jquery.com/jquery-3.3.1.min.js"   integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="   crossorigin="anonymous"></script>
    <script type="text/javascript" src="{{ get_url('static', path='js/handlers.js') }}" charset="utf-8"></script>
  </head>
  <body>
    {{!base}}
  </body>
</html>

The index template, which inherits from the base template is pretty simple. I have an empty div tag where some data will go when the page loads, and a button.

%rebase('templates/base.tpl', title='Index')
<p>Hallo</p>
<div id="data"></div>
<button class="btn btn-default" id="first-btn">Click</button>

Finally, handlers.js hits our /data endpoint when the page loads, and provides some behavior (an alert) when we click a button on the page.

$(document).ready(function() {
  $.get('/data', function(data, status) {
    $('#data').append("Data: "+data)
  })
  $('#first-btn').click(function(){
    alert("Hallo");
  });
});