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

__END__

=pod

=encoding UTF-8

=head1 NAME

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

=head1 VERSION

version 0.073

=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. The basic app
also takes any other files (HTML, images, audio, video, and other
formats) and copies them into the deployed site..

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

=head2 Add the New Apps

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

    # site.yml
    site:
        class: Statocles::Site
        args:
            apps:
                blog:
                    $ref: blog_app
                basic:
                    $ref: basic_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
            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: '.'

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

    site:
        class: Statocles::Site
        args:
            apps:
                blog:
                    $ref: blog_app
                basic:
                    $ref: basic_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 the appropriate configuration to the site object or
app objects.

=head2 Shortcut Icons

To add a shortcut icon to your site, place the image file anywhere that
will be deployed (if you're using the configuration above, you can put
it in the root). Then, add an C<icon> property to the C<images> key of
the C<site> object, like so:

    site:
        class: Statocles::Site
        args:
            images:
                icon:
                    src: /favicon.png

For more information, see L<the C<images> attribute
documentation|Statocles::Site/images>.

=head2 Additional Stylesheets and Scripts

You can easily add extra scripts and stylesheets by adding them to the
site's C<links> attribute:

    site:
        class: Statocles::Site
        args:
            links:
                stylesheet:
                    - href: /css/site.css
                script:
                    - href: /js/site.js

Create the files C</css/site.css> and C</js/site.js> and they will be
picked up by the C<basic_app> we created, above. If you accidentally
create a link to a file that doesn't exist, Statocles will warn you.

=head2 Service Integration

There are third-party services that can be integrated into your site by
adding keys to the C<data> configuration section.

=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
