package Bigtop::Docs::TentTut;

=head1 Name

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

=head1 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.

=head1 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 in
which to place 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:
C<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.

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 will not only start the 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.  This time, we'll actually start using it.

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

=head1 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:

=for html <img src='http://www.usegantry.org/images/tenttut/tentopening.png' alt='tentmaker opening screen />

    http://www.usegantry.org/images/tenttut/tentopening.png

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.  Below those choices
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.

At the bottom of the pane is a section called 'Current bigtop file.'
It shows 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.

In total, there are five tabs:

=over 4

=item Bigtop Config

We just walked through this.  It controls only three things: the app name,
what engine will serve it, and what type of templates it will use.
But it also provides a snapshot of the bigtop file and a way to save it.

=item App Body

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

=item Backends

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

=item App Level Statements

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

=item App Config

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.

=back

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

=head1 App Body

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

=for html <img src='http://www.usegantry.org/images/tenttut/appbody.png' alt='App Body' />

    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' at the top of the address table's box.

Scroll down until you see the Field Quick Edit table.  There will be five
fields at the outset.  The first one is a unique integer primary key called
-- cleverly enough -- id.  The last two 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 go back to the first pane ('Bigtop Config'), 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.

=head1 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 Postgres 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|myslq -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.

=head1 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 don't always have
enough of it to completely satify 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'

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.
In this case I used a bit of ASCII art to indicate that I want a table
called bday with a foreign key to the existing address table.

See tentmaker's perldoc for a complete description of ASCII art.

=head2 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.

Before we start with our changes -- and this is always a good first step
when you've already created the app -- go to the 'Backends' tab and check
the 'No Gen' box for Init Std.  We don't need it any more and it tends to
overwrite things we need (like our Changes file).  Alternatively, you could
check the boxes next to the things you don't want updated.  For example,
you could tell Bigtop to keep its hands off the README and Changes files
while allowing it regenerate the others when it feels like it.

By checking 'No Gen' instead of deselecting the backend, you allow it to
keep registering its keywords, so you don't have to alter the rest of the
file.  This doesn't really matter for Init Std, since all the keywords
it registers are also registered by others.  It is a real issue
for the other backends.

With that bit of housekeeping out of the way, we can begin to make our
changes to the app.  Click on the 'App Body' tab.  Then click on edit
for the C<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.

=head2 Regeneration

Now press 'Save As:' (the name should already be correct) on the Bigtop
Config tab.  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 Postgres 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.

=head1 Further Reading

See Bigtop::Docs::TentRef for more details on what tentmaker can control.
Try Bigtop::Docs::Cookbook for small problems and answers,
Bigtop::Docs::Tutorial for a more complete example, with discussion,
Bigtop::Docs::Keywords for a list of valid keywords and their meanings,
and Bigtop::Docs::Sytnax for full details.  If you need to write your
own backends, see Bigtop::Docs::Modules.

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

=head1 Author

Phil Crow

=cut
