The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

Name

Bigtop::Docs::TentTut - tentmaker tutorial (best viewed in html)

Intro

If you don't know what Bigtop is, you might want to start by reading Bigtop::Docs::About. It will give you a little background and some advice on which other docs to read.

Bigtop is a language of simple structure, but with many keywords. In an effort to make it easier to use, I have written tentmaker, which is a guided editor for building web apps. It understands almost all the features of bigtop syntax, allowing you to conentrate on what you want rather than on proper bigtop spelling and punctuation.

This document is a tutorial to get you started. It is not complete. If you need more details consult Bigtop::Docs::TentRef or Bigtop::Docs::Syntax (or even Bigtop::Keywords).

Here, I will walk you through using tentmaker to generate a bigtop file. Then, I will show how to use bigtop to turn that into a web app. Finally, I will return to expand the example in addtional iterations of feature additions. There are a couple of screen shots here. If you don't see the pictures in line, look for them in the docs directory of the Bigtop distribution and/or on the web at http://www.usegantry.org/images/tenttut.

The example app I will build here is a contact database. It will initially store names and phone numbers. In the second iteration I will expand it. The ostensible purpose is to put my wife's address book on-line.

Starting tentmaker

Before using tentmaker, you must install Gantry (and the Template Toolkit). Then you must install Bigtop, answering yes when asked if you want to install tentmaker's templates (you must also provide a writeable directory for them).

Once Bigtop installation is complete, you may start tentmaker by typing:

    tentmaker

But it is better to use some command line arguments. First, by default tentmaker listens on port 8080. If you want (or need) it to use a different port supply it like so:

    tentmaker --port=8081

tentmaker is very quiet, but when it starts it will tell you something like: HTTP::Server::Simple: You can connect to your server at http://localhost:8081/. This is testament to my laziness as the line reveals HTTP::Server::Simple as that actual server. But you don't need to think about tentmaker as a server (except to realize that it is listening on a port, so be careful of who is allowed to talk to it, think firewall). You need to know how to use it as an app, read on.

(Note that you may use -p instead of --port.)

If you already have a bigtop file, you can put that directly on the command line, tentmaker will open it for editing:

    tentmaker existing.bigtop

Since you probably don't have a such a file handy (although there are some in the examples directory of the bigtop distribution), you should start more like this (adding the --port flag as needed):

    tentmaker --new Contact address

This is how I started tentmaker for the discussion that follows.

This will not only start tentmaker, it will generate a new bigtop file for building the Contact application with a single table called address. When you type this, tentmaker will start with the same message it showed above.

The command line flags can be abbreviated with a single dash and their first letter (e.g. --new is also -n).

You can even specify the columns and their types for tables like address:

    tentmaker --new Contact 'address(name,street,city,state,zip)'

This is how I would have started tentmaker, if I were doing this project on my own. You need to see a few things that this method would have skipped.

Note that single quotes are probably necessary to keep the shell from interpretting the punctuation.

See Bigtop::Docs::ScriptHelp::Style::Kickstart for a complete description of how to define tables and their relationships from the command line.

Building an App

Start a web browser and point it to the server. (The browser needs to understand the Javascript DOM1 standard or a good approximation of it, like Firefox and Safari do. If your browser should understand that standard, but can't handle tentmaker, please send me a bug report.) You should see something like this:

tentmaker opening screen />

<pre><code>    http://www.usegantry.org/images/tenttut/tentopening.png</code></pre>

<p>The page is composed of a set of tabbed panes. The first pane allows you to change the app name, the web server engine which will run it, and the templating system which will generate its output. You can also enter a space separated list of framework plugins you want to use.</p>

<p>Above the tabbed pane is a Save As button and the file name. If you started without providing a file (as I suggested above) the file name box will be blank. Next to 'Save As' is a 'Stop tentmaker' button. This is the best way to stop tentmaker. If you kill it at the command line with control-C, your browser will not know that. Caching pages which no longer function will ensue and confusion is inevitable.</p>

<p>At the bottom of the pane is a section called 'Current bigtop file,' which is initially concealed. If you click the link, it will show the text of the bigtop file you are editing. I included it mostly for debugging, but enquiring minds might want to look at it from time to time as we move through our examples. There are definitely times when its compact form makes spotting errors easier.</p>

<p>In total, there are five tabs:</p>

<dl>

<dt id="Bigtop-Config"><a id="Bigtop"></a>Bigtop Config</dt>
<dd>

<p>We just walked through this. It controls only four things: the app name, what engine will serve it, what type of templates it will use, and what plugins you want. But it also provides a snapshot of the bigtop file.</p>

</dd>
<dt id="App-Body"><a id="App"></a>App Body</dt>
<dd>

<p>The heart of the matter. This pane allows you to define and edit your tables and controllers. More on this below.</p>

</dd>
<dt id="Backends">Backends</dt>
<dd>

<p>Controls what will be generated by bigtop. For example, do you want SQLite, MySQL, or Postges SQL syntax for building your database.</p>

</dd>
<dt id="App-Level-Statements"><a id="App1"></a>App Level Statements</dt>
<dd>

<p>Allows input of general information about the app, like the app's license, who wrote it, and how to contact them.</p>

</dd>
<dt id="App-Config"><a id="App2"></a>App Config</dt>
<dd>

<p>Allows input of configuration information about the app. This usually includes things like database name, user, and password, but can include any configuration your app needs.</p>

</dd>
</dl>

<p>For our first cut at the address book app, we need only visit the App Body pane.</p>

<h1 id="App-Body1"><a id="App3"></a>App Body</h1>

<p>Click on the 'App Body' link. What you see depends on how you started tentmaker. If you did what I did (<code>tentmaker --new Contact address</code>), you will something like this:</p>

<img src=
    http://www.usegantry.org/images/tenttut/appbody.png

This shows that tentmaker has graciously created an address table and a corresponding Address controller. That's what we asked for. Let's fix them so they will really work for an address book.

The main problem with tentmaker's efforts is the column names. We told it the table name, so it used that to infer a variety of other names -- like the controller name. But we didn't give any hints about the columns. To fix that click 'edit or hide' at the top of the address table's box. This will expand to show all the editable features of the table. To collapse the box, click 'edit or hide' again.

Scroll down until you see the Field Quick Edit table. There will be four fields at the outset. (There is also a unique integer primary key called -- cleverly enough -- id, but it doesn't appear in the quick edit box. I rarely want to change it, and it is more complex than the other fields.) The last two default fields are created and modified dates. Those can all stay as they are. But we need to change ident and description to something more meaningful for our address book example. Let's use 'name' and 'number.'

Click into the name box for the ident field and change it to 'name.' Then do the same to change description to 'number.' Almost all changes in tentmaker take effect as soon as you click outside the input box. But, if it makes you feel better, you may click the 'Apply Quick Edit' button.

As an optional extra, this would be a good time to create some additional fields. For Lisa's address book we need street, city, state, zip, and country. It might also be nice to add cell_phone and email. Lisa also insists on the importance of tracking relationship. Feel free to put some or all of those in.

Note that you can make all the new fields in one shot by typing their names with separating spaces in the the 'Name(s)' box under Create Field.

Their labels will be set to their names split on underscore with the first letter of each word capitalized.

Now scroll to the top of the page, enter a file name in the save as box and press the button. You should see a short message below the button which reads, 'Saved contact.bigtop' -- presuming you called your contact.bigtop. If anything goes wrong with the saving, the error will be reported instead. At this point we are ready to build and start the app. This is a good time to press the 'Stop tentmaker' button (presuming the saving went well).

Building and Starting

To create the app, type (assuming you saved the file as contact.bigtop):

    bigtop --create contact.bigtop all

This tells bigtop to create an app from scratch based on contact.bigtop and to build everything it can. We have three steps left, as bigtop will tell you.

Change to the Contact directory. There you will see many familiar things that h2xs would build for you, with some additions and a few twists. For instance, Bigtop apps use Module::Build instead of MakeMaker.

We need to build the database. If you use sqlite (as I will for the examples in this document), it as simple as:

    sqlite app.db < docs/schema.sqlite

This step is so simple, bigtop tries to do it for you. The message it prints will tell you whether or not it worked.

The name app.db was one of the defaults tentmaker chose for us, we could change it in tentmaker (it is part of the dbconn string which appears on the App Config tab).

If you use PostgreSQL or MySQL, you'll need to create the database first, then use your command line tool to populate it. Note that there are three schema files in the docs directory, pick the one that ends with your database name.

Finally, start the server:

    ./app.server [ -d Pg|mysql -u dbuser -p dbpassword ] [ port ]

By default app.server runs on port 8080 and uses the sqlite app.db database. To change the port, type the number directly on the command line (note that this is different from how you specify it for tentmaker):

    ./app.server 8080

To change the database engine and/or supply user and password information, either edit the script, or use the command line options as shown above in brackets. Using command line options is preferable. That way you can let bigtop keep recreating the app.server script as the data model and controller collection grows.

Upon start up, app.server will print a list of the URLs it can serve. Point your browser to them to play with the application.

Iteration Number Two

Now that we have built the app, the inevitable change requests have arrived. While our user likes the basic data we are collecting, she doesn't always have enough of it to completely satisfy our form. Sometimes she has only a phone number or email address. Other times, her friends don't even have email. We need to make most of the fields optional.

Looking a little closer at the existing address book, I noticed that there are some random birth dates scribbled on the end papers. Perhaps we should add a birthday table to better track little nieces and nephews who might periodically receive gifts.

From the build directory (where you ran app.server in the last section), restart the tentmaker like so:

    tentmaker --add docs/contact.bigtop 'bday->address'

As with the --new flag, --add allows you to define columns for the new tables. Existing tables will receive new foreign keys as specified, but can't be modified in other ways from the command line. See Bigtop::ScriptHelp::Style::Kickstart for how to specify columns, their types and a few other things from the command line. Note that both tentmaker and bigtop share command line handling code, so all examples for bigtop work equally well for tentmaker.

Provide a port if you need it (with --port).

We could have said:

    tentmaker docs/contact.bigtop

But then we would have had to do all the work. By telling tentmaker that we want to add to the bigtop file, it can do some more work for us.

Core Goals

Now there are two main things we want to do: make most of the address table fields optional and pick better names for the generated bday table. Both of these could also be acheived by careful command line column specifications when we built the tables above, see Bigtop::ScriptHelp::Style::Kickstart.

Even if you do supply better names during initial table generation, this section still offers good advice should ever need to make changes to what you specified on the command line. Further, tentmaker allows you to edit far more than you can control from the command line.

Ask your browser for a full page refresh (hold shift and press the refresh button. Then, click on the 'App Body' tab. Then click on edit for the address table. Go back to the Field Quick Edit box and begin checking the optional box for all the fields which should be optional. Or, as a better alternative in this case, click the optional box in title row of the quick edit table. This will make all the fields optional. Then, uncheck the required fields. In our case, that should only be 'name.'

The other changes are reminscent of the field name changes and additions we did earlier. To make them, edit the new bday table. Then change the names of the ident and description fields to 'name' and 'bdate.' Make sure that bdate's SQL type is date.

Regeneration

Now press 'Save As:' (the name should already be correct). Then, at a command line in the build directory (the one with Build.PL) type:

    bigtop docs/contact.bigtop all

Now we have a bit of work to do on the actual database. We have two choices: (1) destroy the original database or (2) alter the original database to match the new model. In this case, I'll opt for number 1 since we haven't put any real data into the database yet. This is convenient, since Bigtop does not help with table alterations and my version of SQLite doesn't support them.

These are the steps for sqlite:

    rm contact
    sqlite contact < docs/schema.sqlite

For PostgreSQL or MySQL it takes a bit more work:

    remove the old contact database
    create a new contact database
    use the database command line tool to populate the database

Once the database is ready, you can restart the server:

    ./app.server

Go to the address page and click on 'Add' and see that most fields are now optional. Then go to the bday page and 'Add' a birthday. Note the pull down list of families we could associate with this birthday person. Also note the 'Date Select' link which pops up a calendar for easy date picking.

You can continue to develop and regenerate as the model changes. The only piece that is difficult to manage is the database once it is built.

Further Reading

See Bigtop::Docs::TentRef for more details on what tentmaker can control. For more command line options, including firing up tentmaker to build an app based on an existing PostgreSQL 8 database, see Bigtop::ScriptHelp::Style::Pg8Live. Try Bigtop::Docs::Cookbook for small problems and answers, Bigtop::Docs::Tutorial for a more complete example, with discussion, Bigtop::Docs::AutoKeywords for details on all bigtop keywords and Bigtop::Docs::Sytnax for an explanation of bigtop file structure. If you need to write your own backends, see Bigtop::Docs::Modules.

All of the doc modules are described briefly in Bigtop::Docs::TOC.

Author

Phil Crow