# PODNAME: Statocles::Help::Config
# ABSTRACT: A guide to configuring a Statocles site

__END__

=pod

=head1 NAME

Statocles::Help::Config - A guide to configuring a Statocles site

=head1 VERSION

version 0.045

=head1 DESCRIPTION

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

This document explains how to build a configuration file without using
the C<statocles create> command.

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

    $ mkdir blog

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

    # site.yml
    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</>, later).

=head2 A Deploy

To deploy our site to Github, we need to build a L<deploy
object|Statocles::Deploy> for Git repositories using
L<Statocles::Deploy::Git|Statocles::Deploy::Git>. Our deploy object will copy
our built pages into the Git repository and commit them. Our deploy will happen
in the root directory of our site on the C<gh-pages> branch.

    # site.yml
    github_deploy:
        class: Statocles::Deploy::Git
        args:
            branch: gh-pages

Though we are going to deploy to Git, we could also deploy to SFTP or FTP or
transfer the pages to a CDN. See L<Statocles::Help::Deploy> for more information.

=head2 A Theme

We could set up a theme (L<Statocles::Theme|Statocles::Theme>) to change how
our site looks, but for now, we'll use the C<default> theme included with
Statocles. See L<Statocle::Help::Theme> for information on how to change and
customize your theme.

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

    # site.yml
    site:
        class: Statocles::Site
        args:
            apps:
                blog:
                    $ref: blog_app
            deploy:
                $ref: github_deploy
            title: My Site
            index: blog
            nav:
                main:
                    - title: Blog
                      href: /

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).

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</>.

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.

    # site.yml
    blog_app:
        class: Statocles::App::Blog
        args:
            url_root: /blog
            store: 'blog'

    github_deploy:
        class: Statocles::Deploy::Git
        args:
            branch: gh-pages

    site:
        class: Statocles::Site
        args:
            apps:
                blog:
                    $ref: blog_app
            deploy:
                $ref: github_deploy
            title: My Site
            index: blog
            nav:
                main:
                    - title: Blog
                      href: /

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.

See L<Statocles::Help::Content> for more information about editing the site's
content.

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

    # site.yml
    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.

    # site.yml
    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.yml
    site:
        class: Statocles::Site
        args:
            apps:
                blog:
                    $ref: blog_app
                plain:
                    $ref: plain_app
                static:
                    $ref: static_app
            deploy:
                $ref: github_deploy
            title: My Site
            index: blog
            nav:
                main:
                    - title: Blog
                      href: /

=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 daemon> to test the new page.

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

    # site.yml
    site:
        class: Statocles::Site
        args:
            apps:
                blog:
                    $ref: blog_app
                plain:
                    $ref: plain_app
                static:
                    $ref: static_app
            deploy:
                $ref: github_deploy
            title: My Site
            index: blog
            nav:
                main:
                    - title: Blog
                      href: /
                    - 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:

    # 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:
        class: Statocles::App::Static
        args:
            url_root: '/static'
            store: 'static'

    github_deploy:
        class: Statocles::Deploy::Git
        args:
            branch: gh-pages

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

            deploy:
                $ref: github_deploy

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

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

=head1 SEE ALSO

=over 4

=item L<How to edit content with Statocles|Statocles::Help::Content>

=item L<How to deploy a Statocles site|Statocles::Help::Deploy>

=item L<How to customize a Statocles theme|Statocles::Help::Theme>

=back

=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
