5 min read Author: klaas

Working with views

Scaffolding a html web frontend  

As you might know from Rails we use scaffolding for to generate our html web views quickly and easily. Since we also rely on convention over configuration we do not have to configure anything beforehand. By scaffolding you can automatically generate hmtl frontends to manage you models online. This might useful even if you don't need html as a user interfcace since it eases data management for you during developoment. 

You shoud have already generated an application, created a model and added a handler to your app. If you haven't done this so far just follow the getting started tutorial. It also just takes a few minutes to set this all up. For this hands on tutorial I assume that your model and handler are called todo.

This is the idea of PythonOnWheels, to make the basic things as easy as possible to focus on the app, not on the boilerplate.

Conventions

All views, no matter if you create them manually or scaffold them, are placed in the views directory of your application. The convention is that there is a subdirectory for every handler that supports html output. The generator create a subdirectory and will scaffold views for the typical REST routes we just created in our handler.  This means we will get the following views for their according REST methods.

views\handler_name\list 
page
edit
show
new

Supported CSS Frameworks

As of today PoW supports bootstrap 4 and semanticUI as frontend frameworks. Bootstrap 4 is the default.

Lets create the views

To create a scaffolded view you execute the generate_scaffold.py generator and give it the handler name it should link to with -n handler_name and the view-type it should generate with -t <tpye> (bs4 bootstrap4 or sui for semanticUI). So execute this to generate a whole set of views for all our REST methods. 

python generate_scaffold.py -n todo -t bs4

This will generate the follwing output:

CamelCased handler name:  Todo 
----------------------------------------
generating Scaffolds for: todo
view_type: bs4
----------------------------------------
... created view: c:\khz\devel\todo\views\todo\todo_show.tmpl
... -> using template: scaffold_show_view.bs4
... created view: c:\khz\devel\todo\views\todo\todo_list.tmpl
... -> using template: scaffold_list_view.bs4
... created view: c:\khz\devel\todo\views\todo\todo_page.tmpl
... -> using template: scaffold_page_view.bs4
... created view: c:\khz\devel\todo\views\todo\todo_edit.tmpl
... -> using template: scaffold_edit_view.bs4
... created view: c:\khz\devel\todo\views\todo\todo_new.tmpl
... -> using template: scaffold_new_view.bs4

That's it. When you stick to the conventions that you give model, handler and view the same name everything works seamlessly without further configuration.

Start the server and check the views. Point your browser to localhost:8080/todo 

The list view

If you click on create this will send an HTTPO request to http://localhost:8080/todo/new which will call the todo handler's new method which in turn renders the todo_new.tmpl view. 

The new view

 

Let's check the list view again

You can see that the newly created model was saved to the DB and is accessibly in the view. You have the options to show, edit and delete the model. (Be carefull, delete will not ask you another quiestion. IT just deletes)

The generated views are tornado templates, which is a mustache alike template language which gives you great flexibility to design dynamic html views based on bootstrap4 or semanticUI

Configuration options

Although we rely on conventions to have the quickest workflow there are some options you can configure if you like or need. You can change the default action called (and hence the default view rendered) for the default REST route:

config.py: 
"default_rest_route": "list",

Setting this to page will call the page action when using the route localhost:8080/todo

You can also set the default list separator (default = Space) 

"list_separator"    :   " ",

The template_path (but normally you should keep this)

"template_path"     :   os.path.join(os.path.dirname(__file__), "views"),


Next steps:

  • Play around a little, create, edit, delete some models. 
  • Inspect the templates and make some changes using the template or bootstrap4 docs.