Hello LiveReload

Let’s get some bits on the screen. In this step we’re going to make a small Bottle application which returns an HTML template and the two script tags to load our Hyperapp files.

LiveReload

Make a file run_server.py with the following:

import bottle
from bottle import route, default_app, static_file
from bottle import template
from livereload import Server

bottle.debug(True)


@route('/')
def index():
    return template('index', state=dict(count=0))


@route('/<filepath:path>')
def server_static(filepath):
    return static_file(filepath, root='.')


if __name__ == '__main__':
    app = default_app()
    server = Server(app)
    server.watch('index.css')
    server.watch('counter.js')
    server.watch('index.tpl', ignore=False)
    server.serve()

This is a simple Bottle app with two routes:

  • / uses a Bottle template at index.tpl to dynamically render a response
  • Everything else is served as static files from the root directory.

Template

Now make index.tpl:

<html>
<head>
    <title>Transcrypt Hyperapp</title>
    <link rel="icon" type="image/x-icon"
          href="https://www.python.org/static/favicon.ico">
    <link rel="stylesheet" href="index.css"/>
    <script src="hyperapp.js"></script>
    <script src="hyperappHtml.js"></script>
</head>
<body>
<h1>Transcrypt + Hyperapp Demo</h1>
<p>This sample application has a counter. On first load, the counter
    renders, server-side, the HTML. After that, client-side events
    re-render the counter.</p>
<div id="counter">
    <div>
        <h3>Counter Demo</h3>
        <p>Current Count: {{ state['count'] }}</p>
        <button>-</button>
        <button>+</button>
    </div>
</div>
<script src="counter.js"></script>
</body>
</html>

This template is passed in the “state” of the application. It inserts the count value, as well as includes script and link tags for the static assets.

As this shows, when the browser makes a request to the URL, you get “server-side rendering”: the current value of count is inserted, as well as the two buttons which will later be made dynamic.

JS

As a placeholder for the next step, create counter.js:

console.log('Loaded')

CSS

Not much in index.css:

body {
    font-family: "Helvetica Neue", sans-serif;
    margin: 2em 20em 2em 2em;
}

#counter {
    margin: 2em;
    padding: 1em;
    border: solid gray 1px;
}

Running

With that in place, let’s run the server:

$ python ./run_server.py

Open http://127.0.0.1:5500/ in a browser, preferably with the dev console open. You get the first render.

Now try editing the run_server.py and changing the initial count. The application restarts and you see the new value.

Now edit index.tpl and index.css. The changes update much faster, as the Python process doesn’t restart. Instead, the server tells the browser to reload.