# PODNAME: Statocles::Help::Setup
# ABSTRACT: A guide to setting up a new Statocles site

__END__

=pod

=head1 NAME

Statocles::Help::Setup - A guide to setting up a new Statocles site

=head1 VERSION

version 0.033

=head1 DESCRIPTION

This document describes how to set up a simple blog web site suitable to
be deployed to GitHub Pages using Statocles.

=head1 Building site.yml - The Main Configuration File

Statocles uses L<Beam::Wire|Beam::Wire>, a dependency-injection module, for
configuration. The format is L<YAML|http://yaml.org> and contains the data
needed to build the objects: Arguments to the object's constructor.  This means
that any C<ATTRIBUTES> defined in the documentation can be used in the
configuration file.

The configuration file is, by default, called C<site.yml>. See
L<the statocles command documentation|statocles> if you want to have multiple
site configuration files.

=head2 A Source

Statocles takes simple, YAML-and-Markdown-formatted
L<document|Statocles::Document> files and builds HTML pages out of them.

So we need a place to put our source documents. A L<store|Statocles::Store>
fills multiple roles relating to reading and writing files. Right now, we need
it to hold on to our blog posts. We'll put our blog posts in the C<blog>
directory.

The L<blog application|Statocles::App::Blog> will use this store to add new
blog posts and build web pages from the documents in the C<blog> directory.
More on that later.

=head2 An App

A L<Statocles app|Statocles::App> is the driver that turns documents into
L<pages|Statocles::Page>. To build pages, we need a store full of documents. We
define our store with the string C<blog>, which will get magically coerced into
a L<file store object|Statocles::Store::File>.

Since we're building a blog site, we'll use the
L<Statocles blog app|Statocles::App::Blog>:

    blog_app:
        class: Statocles::App::Blog
        args:
            url_root: /blog
            store: 'blog'

We put our blog app under the root URL C</blog>. All pages that come from this
app will start with C</blog> (except the index page, we'll move that to
C</index.html>, later).

=head2 A Destination

Before we can generate pages, we need a place to put them. Statocles needs two
places, a build directory (a staging area), and a deploy directory (the final
destination for the site).

For our site, we will make a C<build> directory for our staging area, where we
can verify that our site looks correct before we deploy. Our deploy will happen
in the root directory of our site (C<.>). This is good for a GitHub Pages site.

Make sure both of these directories exist:

    $ mkdir build

Though stores are usually just directories, they could also perform an SFTP or
FTP or transfer the pages to a CDN (I think I have some evolution to do here).

=head2 A Theme

Last thing we need before we can build our site is a theme. A theme
(L<Statocles::Theme|Statocles::Theme>) builds and parses templates into
L<Statocles::Template|Statocles::Template> objects. We'll use the Statocles
default theme, included with the module. The special C<::default> string will
look in the Statocles C<share/theme> directory.

=head2 A Site

Now that we're ready, we can tie it all together. A L<site|Statocles::Site> is
a collection of apps that build and deploy to the same place. The special L<git
site|Statocles::Site::Git> knows how to deploy to git repositories.

    site:
        class: Statocles::Site::Git
        args:
            theme: '::default'
            apps:
                blog:
                    $ref: blog_app
            build_store: 'build'
            deploy_store: '.'
            deploy_branch: master
            title: My Site
            index: blog
            nav:
                main:
                    - title: Blog
                      href: /index.html

We define our theme with the string C<::default>, which will get magically
coerced into a L<theme object|Statocles::Theme>.

When adding apps to our site, we give them a name (in this case C<blog>) so
that we can refer to them on the command-line (later).

Just like the blog store, the C<build_store> and C<deploy_store> will magically
create a Statocles::Store::File object from the path string.

The git branch we want to deploy to is C<master>. As part of the default
template, we can provide a site C<title>.

The C<index> attribute gives the name of the app to use as our index page.
Since we only have one app, we can only give it the C<blog>. Whatever main page
the blog app defines will be moved to the main site index C</index.html>.

Finally, we can define a C<nav> list, again giving a name: C<main>. The
default template uses the C<main> nav across the top.

=head2 The Complete site.yml

Combine it all together and you get this. Feel free to copy and paste to start
your own site.

    blog_app:
        class: Statocles::App::Blog
        args:
            url_root: /blog
            store: 'blog'
    site:
        class: Statocles::Site::Git
        args:
            theme: '::default'
            apps:
                blog:
                    $ref: blog_app
            build_store: 'build'
            deploy_store: '.'
            title: My Site
            index: blog
            nav:
                main:
                    - title: Blog
                      href: /index.html

B<NOTE:> One of the most useful things about using a dependency injection
module is that you can easily plug-in your own classes. If you want to use your
own template format, you can build your own Statocles::Theme class that
provides a different kind of Statocles::Template object and use that instead.
If you want to use your own document format, you can make your own
Statocles::Store class that reads from a database.

=head1 The C<statocles> Command

Now that we have a C<site.yml>, we can run the L<statocles|statocles> command
to manage our site.

=head2 Initialize Your Git Repo

    $ git init
    $ git remote add origin ssh://git@github.com/preaction/preaction.github.io

Before we can get going, we need to create our git repository.

I<NOTE:> In the future I plan to include this as a C<statocles create> command.

=head2 Create A Blog Post

Remember when we gave our blog app a name? Now we can use that name to access
the blog's command-line commands. To create a new blog post, we can use the
C<post> command:

    $ statocles blog post My First Post
    New post at: blog/2014/06/04/my-first-post.markdown

Everything after C<post> will be used as the title of the post.

If you have the C<EDITOR> environment variable set, your editor will
automatically open on the newly-created document.

=head2 Build The Site

    $ statocles build

Running the C<build> command will write all our pages to the C<build> store,
which points to the C<build> directory. We can open up this directory and look
at the files to make sure that our deploy will be correct.

=head2 Test The Site

    $ statocles daemon
    Listening on http://*:3000

Run the C<daemon> command to start an HTTP server to view your built site. This
will automatically build the site, so if you forgot to run C<build>, don't
worry.

If you edit any content, running C<build> again will update the site. On Mac
OS X, editing any content will automatically rebuild the site.

=head2 Commit Your Changes

    $ git add blog/2014/06/04/my-first-post.markdown
    $ git commit -m'My first post'

Once the build looks good, we'll want to commit our changes. The major feature
of having a website in a git repository is change tracking.

=head2 Deploy The Site

    $ statocles deploy

Running the C<deploy> command will, in the case of the git site, commit the
updated pages to the git repository. C<deploy> will try to do a C<git push>
automatically, so your changes are now live on Github Pages!

=head1 Adding More Apps

In addition to our blog app, we also want to add some plain Markdown content, and some
images.

=head2 Plain Markdown

For plain markdown, there is the L<plain app:
Statocles::App::Plain|Statocles::App::Plain>. The plain app takes the same
YAML-and-Markdown-formatted documents as the blog app and creates HTML pages,
without the lists, tags, and feeds the blog generates.

Like the blog, we need a store to find our documents. This time, we'll use the
root directory of our repository, C<.>. Finally, we'll need a URL root. Since
we're using the root directory for our documents, we'll use the root URL for
our destination C</>.

    plain_app:
        class: Statocles::App::Plain
        args:
            url_root: '/'
            store: '.'

Now we just need to add this app to our site, but before we do, we'll create an
app for our static files.

=head2 Static Files

Lastly, we wanted a place to put any file at all. No processing. No templates.
Just a simple copy from one store to another. For this one, we'll put
everything in the C</static> directory, and give a URL root to match.

    static_app:
        class: Statocles::App::Static
        args:
            url_root: '/static'
            store: 'static'

=head2 Add the New Apps

To enable the new apps, we just need to add them to the site's C<apps>.

    site:
        class: Statocles::Site::Git
        args:
            apps:
                blog:
                    $ref: blog_app
                plain:
                    $ref: plain_app
                static:
                    $ref: static_app

=head2 Add Plain Content

Now, we just need some content for our plain app to deploy. The plain app uses the same
format as the blog, so we need a YAML header followed by some Markdown content:

Create a file named C<about.markdown> with the following content:

    ---
    title: About
    ---
    # About Me

    This is a personal website!

Then, run C<statocles build>. The C<about.markdown> turns into C<about.html> in
our C<build/> directory.

Now we should probably make a link in our main nav to the new about page:

    site:
        class: Statocles::Site::Git
        args:
            # ... [redacted]

            nav:
                main:
                    - title: Blog
                      href: /index.html
                    - title: About
                      href: /about.html

Now, if we run C<statocles build> again, we can see the link in our header.

=head2 The Complete site.yml - With More Apps

Along with the blog app and our other settings, here is our new, complete site.yml:

    blog_app:
        class: Statocles::App::Blog
        args:
            url_root: /blog
            store: 'blog'

    plain_app:
        class: Statocles::App::Plain
        args:
            url_root: '/'
            store: '.'

    static_app:

    site:
        class: Statocles::Site::Git
        args:
            theme: '::default'
            apps:
                blog:
                    $ref: blog_app
                plain:
                    $ref: plain_app
                static:
                    $ref: static_app

            build_store: 'build'
            deploy_store: '.'

            title: My Site
            index: blog
            nav:
                main:
                    - title: Blog
                      href: /index.html
                    - title: About
                      href: /about.html

If we're satisfied with our new About page, we can deploy our site with
C<statocles deploy>.

=head1 AUTHOR

Doug Bell <preaction@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2015 by Doug Bell.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
