# 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.064

=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<store object|Statocles::Store>.

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<Statocles::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 path to the page to use as our index page.
Since the blog's C<url_root> is C</blog>, this will move the main blog page
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 Basic Pages

For basic pages with no structure or extras, there is the L<basic app:
Statocles::App::Basic|Statocles::App::Basic>. The basic 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
    basic_app:
        class: Statocles::App::Basic
        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
                basic:
                    $ref: basic_app
                static:
                    $ref: static_app
            deploy:
                $ref: github_deploy
            title: My Site
            index: /blog
            nav:
                main:
                    - title: Blog
                      href: /

=head2 Add Basic Content

Now, we just need some content for our basic app to deploy. The basic 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
                basic:
                    $ref: basic_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'

    basic_app:
        class: Statocles::App::Basic
        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
                basic:
                    $ref: basic_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 DEFAULT THEME FEATURES

There are special features built-in to all default themes that can be enabled
by adding C<data> sections to the site object or app objects.

=over 4

=item Disqus

Disqus is a free, hosted comment system that can be easily added to static
sites to provide some user interaction.

To add L<Disqus comments|http://disqus.com> to your blog, add your Disqus
shortname (from C<http://YOUR_NAME.disqus.com/admin>) to the site data, like
so:

    # site.yml
    site:
        class: Statocles::Site
        args:
            # ...
            data:
                disqus:
                    shortname: 'YOUR_NAME'

This will add a comments section to the bottom of your blog posts, and show
the number of comments in the blog list pages.

=over 4

=item *

L<What is a short name?|https://help.disqus.com/customer/portal/articles/466208>

=item *

L<Sign up for Disqus|https://disqus.com/admin/signup/>

=back

=back

=head1 ADVANCED CONFIGURATION

The configuration file is a L<Beam::Wire> container. This means that any
object attributes (in the C<ATTRIBUTES> section of their documentation)
can be set from the config file.

=head2 Plugins

Additional functionality can be added by plugins using the site's
C<plugins> attribute:

    # site.yml
    site:
        class: Statocles::Site
        args:
            # ...
            plugins:
                highlight:
                    $class: Statocles::Plugin::Highlight
                    $args:
                        theme: solarized-light

Each plugin has a name (C<highlight>), and requires a C<$class> (the
class name of the plugin) and optional C<$args> (the plugin's
attributes).

See L<the list of bundled plugins|Statocles::Plugin/BUNDLED PLUGINS>.

=head2 Custom Markdown

To use a custom Markdown parser, like L<Text::MultiMarkdown>, which has L<some
extra syntax
features|https://rawgit.com/fletcher/human-markdown-reference/master/index.html>,
you can use the L<site object's C<markdown> attribute|Statocles::Site/markdown>
to configure a custom object with C<$class> and optional C<$args>:

    # site.yml
    site:
        class: Statocles::Site
        args:
            # ...
            markdown:
                $class: Text::MultiMarkdown
                $args:
                    use_metadata: false

=head1 SEE ALSO

=over 4

=item L<Statocles::Help::Error - How to fix error messages from Statocles|Statocles::Help::Error>

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

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

=item L<Statocles::Help::Theme - 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) 2016 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
