=head1 NAME

Miril::Manual - Why and how to use Miril, the static content management sytem.

=head1 WHAT IS SPECIAL ABOUT MIRIL

=over

=item * 

Miril is written in perl and uses the L<CGI::Application> framework. 

=item * 

Miril stores your data in a backend (text files, a database, etc.) and publishes it to static pages. Unlike homegrown static publishing solutions (e.g. scripts using the Template Toolkit), Miril provides a nice user interface for editing content.

=item * 

Miril has been designed from the very start to be extremely easy to deploy. The main distribution only has pure-perl dependencies. The immediate plans include bundling all prerequisites in a single file and shipping Miril as a standalone cgi script, to that installing on a typical shared host should be a no-brainer.

=item * 

Miril has been designed with small to medium-sized websites in mind, i.e. websites with hundreds of pages as opposed to thousands of pages. If you have a typical small website such as a corporate website or a personal blog Miril may be a better deal for you than full-blown content management systems since it is faster to deploy, easier to manage, and generally has less administrative overhead both for the site administrator and for the users.

=item * 

Miril has a user interface that has been deliberately kept extremely simple and uncluttered. The goal is for the end users of Miril (those in charge of managing content) to require little or no training to start using it. This means that some of the administrative tasks (such as user management and adding special types of pages) can only be performed by editing the configuration files and templates manually. For a similar reason, Miril also takes a very simplistic approach towards access management and does not provide roles or complex permissions. In fact, Miril has been designed to be used in teams where 1) users generally can trust each other and complicated access management is not necessary and 2) there is at least one tech-savvy user who can take care of the occasional administrative tasks.

=item * 

Miril is extensible. You can (or at least you will be able to in the near future) choose between different storage backends (or models), different templating systems, etc.

=back

=head1 DEPLOYMENT OPTIONS

Miril is run as a cgi script. This means that:

=over

=item *

On a shared host, you can run Miril from your C<cgi-bin> directory. It will run slower than in a C<mod_perl> environment, but since Miril will be used only when managing content this should not be a problem.

=item *

Of course, if you have sufficient control over your environment and the load on Miril demands it, you can accelerate Miril by running it under C<FastCGI> or C<mod_perl>.

=item *

Because Miril ultimately produces static content only, you can run it from your local machine and then synchronize your local output directory with the web server. This way you can manage websites on servers that don't even have C<perl> installed, or where installing Miril would be difficult.

=back

=head1 INSTALLATION

Currently Miril is installable only from C<CPAN>. Simply run C<install Miril> from your favourite C<CPAN> shell. 

=head1 CONFIGURATION

=head2 Create a cgi script

Once you have installed Miril, create a cgi script named C<miril.pl> or C<miril.cgi> with the following content:

  #!usr/bin/perl
  
  use strict;
  use warnings;
  use Miril;

  my $app = Miril->new( PARAMS => { cfg_file => 'miril.config' } );
  $app->run;

Change the shebang line to wherever your C<perl> is located and change C<miril.config> to wherever you configuration file (see below) is located. The configuration file path can be relative to the location of the cgi script. If this option is not provided, Miril will try to load a file named C<miril.config> and located in the same directory as the cgi script itself. Put that script in your C<cgi-bin> directory.

=head2 Create a configuration file

Make sure you create your configuration file in the location that you chose above. Currently only XML is supported for the configuration file format.

=head3 Basic configuration options

A minimal configuration file has the following content:

  <xml>
  
    <data_path>../miril/data</data_path>
    <tmpl_path>../miril/tmpl</tmpl_path>
    <cache_path>../miril/cache</cache_path>
    <cfg_path>../miril/cfg</cfg_path>
  
    <files_path>../htdocs/files</files_path>
    <output_path>../htdocs</output_path>

    <http_dir></http_dir>
    <files_http_dir>/files</files_http_dir>
    <domain>http://www.example.com</domain>

    <secret>Some secret line</secret>

  </xml>

The options are explained here:

=over

=item data_path

This is where Miril stores your content when it uses a file-based model (such as L<Miril::Model::File::XMLTPP>, which is the only model currently available). Miril must have read-write access to this directory.

=item tmpl_path

This is where you are going to put all the templates that Miril will use to build your website (see below). Miril must have read access to this directory.

=item cache_path

Miril may use this directory to store random information. It must have read-write access.

=item cfg_path

This is the directory where the file with information about Miril's users will be located. Miril must have read-write access to this file. You may want to put in in the same directory with your main configuration file.

=item files_path

This is the directory where files (e.g. images, pdf files, etc.) uploaded by Miril users will be stored. Miril must have read-write access to this directory. In a typical installation this directory will be somewhere below your server's document root.

=item output_path

This is the directory where Miril will place all the output files it produces. In a typical installation this directory will be somewhere below your server's document root. 

=item http_root

This is the base URL of your website and Miril will use this string to prefix all URL's that it produces. If your website is located at C<http://www.example.com>, you would set C<http_root> to C<http://www.example.com> to produce fully qualified URL's. If you want your website to have relative URL's, you need to leave this option empty. If your website is located at C<http://www.example.com/mywebsite>, you would set C<http_root> to C<http://www.example.com/mywebsite> for fully qualified URL's and to C</mywebsite> for relative URL's.

=item files_http_root

This option specifies the base URL for accessing the files managed by the C<files_path> option above. It follows the same rules as C<http_root>.

=item domain

If you have specified a relative URL in C<http_root> above, use this option to provide the domain name of your website for cases where fully qualified URL's are needed, such as RSS feeds. Leave empty if you have set C<http_root> to a fully-qualified URL.

=item secret

A random phrase used for security purposes when encrypting authentication data stored in cookies (required by L<CGI::Applciation::Plugin::Authentication::Cookie>).

=item view

Which view module, or templating system, will be used to render your site. Default is C<HTML::Template>, which will load L<Miril::View::HTML::Template>. You can also set this to C<Text::Template>, and additional templating systems may be added in the future.

=back

=head3 Configuring content types

Next you may need to configure your content types. This is what a basic configuration looks like:

  <xml>
  ...

    <types>
      <type>
        <name>Story</name>
        <id>story</id>
        <location>story</location>
        <template>item.tmpl</template>
      </type>
      <type>
        <name>Page</name>
        <id>page</id>
        <location></location>
        <template>page.tmpl</template>
      </type>
    </types>

  ...
  </xml>

You will get these two content types by default if you have not specified your own content types in the configuration file.

=over

=item name

The user-friendly name of the content type, as it would appear to the end user.

=item id

A unique alphanumeric string identifying the content type, used internally by Miril.

=item location

The location, relative to C<output_path>, where Miril will write entries of this content type.

=item template

The template file Miril will use to create html pages of this content type.

=back

=head3 Creating lists

Miril allows you to create special pages which combine data from multiple items - e.g. a list of articles, a RSS feed, etc. This is how you configure lists:

  <xml>
  ...

    <lists>
      <list>
        <id>news</id>
        <template>news.tmpl</template>
        <location>news.html</location>
        <match>
          <type>story</type>
          <status>published</status>
          <last>6</last>
        </match>
      </list>
      <list>
        <id>feed</id>
        <template>atom.tmpl</template>
        <location>atom.xml</location>
        <match>
          <type>news</type>
          <status>published</status>
          <last>10</last>
        </match>
      </list>
    </lists>

  ...
  </xml>

=over

=item id

A unique alphanumeric string identifying the list.

=item template

The template file Miril will use to create this list.

=item location

The location of the file, relative to C<output_path>, where Miril will write this list.

=item match

The C<match> elemement is used to determine which items are included in the list. The filtering criteria are:

=over 2

=item type

Only return items with this type id.

=item author

Only return items with the specified author.

=item topic

Only return items with the specified topic id.

=item last

Only return the N most recent items matching the above criteria.

=back

Only published items can be included in the list (i.e. items whose status is C<published> and not C<draft>).

=back

=head3 Specifying authors

Miril allows you to specify the author of each post. The list of authors is specified in the confuguration file as follows:

  <xml>
  ...

    <authors>
      <author>J. R. R. Tolkien</author>
      <author>J. K. Rowling</author>
    </authors>

  ...
  </xml>

Note that any registered user can specify any author name for any post, so this is used only to display post information in the published site rather than to control access. This is part of Miril's design philosophy (trusted team).

=head3 Specifying topics

Miril has basic support for topics, or categories. The list of topics is specified in the confuguration file as follows:

  <xml>
  ...

	<topics>
		<topic>
			<id>flowers</id>
			<name>Flowers</name>
		</topic>
		<topic>
			<id>animals</id>
			<name>Fuzzy Animals</name>
		</topic>
		<topic>
			<id>bananas</id>
			<name>Bananas</name>
		</topic>
	</topics>

  ...
  </xml>

Each post can then be associated with one or more topics.

=head2 Create a users file

You need a file with information about users and passwords in order to run Miril. The file must be named C<usres.xml> and be located in the directory specified by the C<cfg_path> option in the main configuration file. Currently only XML is supported as the configuration file format. The structure is as follows:

  <xml>
    <user>
      <name>J. R. R. Tolkien</name>
      <password>123456</password>
      <username>tolkien</username>
    </user>
    <user>
      <name>J. K. Rowling</name>
      <password>123456</password>
      <username>rowling</username>
    </user>
  </xml>

Passwords can be stored either in plain text, or encrypted (using the MD5 algorithm). When you create a new user, you initially specify their password in plain text and them tell them to log in with this password but change it immediately afterwards. When a password is changed using Miril's user interface, it  will be stored encrypted in the above XML file. Similarly, if a user has forgotten their password, you can temporarily reset it manually to a plain-text password and ask them to change it again. 

Miril is not accessible to unregistered users. All registered users have identical permissions and can edit and publish all types of content.

=head2 Create your output templates

Once the configuration and users files have been set up, you can run Miril and edit content. In order to publish content, however, you need to provide the templates which will be used to render your pages. The templates are located in the directory specified by the C<tmpl_path> option in the configuration file, and must contain all the templates specified when configuring content types and lists, as well as any additional templates referenced by them (such as headers and footers). Currently the only supported template format is L<HTML::Template> with L<HTML::Template::Plugin::Dot>. The templates are initialised with the C<die_on_bad_params> option set to false, and the C<global_vars> option set to true.

Each template used to generate a page of a certain content type is passed an C<item> paremeter, which is an object containing all information about the item being rendered. The structure of the C<item> object is as follows:

=over

=item item.title

The title of the post.

=item item.id

The alphanumerical id of the post.

=item item.teaser

The teaser of the post, rendered into html.

=item item.text

The full text of the post, rendered into html.

=item item.type

The type of the post (e.g. "page").

=item item.url

The url at which the post will be accessible (e.g. "/news/my_first_post.html").

=item item.full_url

Contains the post url preceded by whatever is in the C<domain> configuration option (e.g. "http://www.example.com/news/my_first_post.html").

=item item.author

The author of the post.

=item item.published.epoch

The time when the post was published, in epoch format (e.g. "1249899886").

=item item.published.epoch

The time when the post was published, in iso format (e.g. "2009-08-10T13:24:46FLE Daylight Time").

=item item.published.num

The date when the post was published, in numeric format (e.g. "2009.08.10").

=item item.published.print

The date when the post was published, in word format (e.g. "Monday, 10 Aug 2009").

=item item.modified.xxx

Same as above, but refers to the time when the post was last modified.

=item topics

An arreyref of topics associated with this post. Each topic is an object with two properties: C<id> and C<name>.

=back

Each template used to generate a list is passed an C<items> paremeter, which is a list of objects containing all information about the items being rendered. The structure of those objects is the same as of the C<item> objects described above.

=head1 USER INTERFACE

Once you have configured Miril, you can access it by typing the url of the cgi script you created, e.g. C<http://www.examle.com/cgi-bin/miril.pl>. Miril's user interface has the following elements:

=head2 Entries

This is the main screen. It displays a list of all content entries. It provides links to search entries or to post a new entry. 

=head2 Files

Displays a list of all files the user has uploaded and a link to a file upload form.

=head2 Edit Item

This screen is displayed when creating a new item or when modifying an existing one. Most of the options should be self explanatory, but there are a few things to keep in mind:

=over 

=item * 

The ID field is an aplphanumeric string which servers as an unique id for this item. Future versions may create this id automatically and hide it from the user altogether. It may be useful, however, to specify it manually, since this id is used to generate the url of the output file (usually by attacing C<.html> at the end) and the user may want to have control over the url for SEO purposes.

=item *

The status field has two options - C<draft> and C<published>. Items marked as C<draft> will be available for viewing and editing from Miril's UI, but will not be published to the live website. 

=item * 

The item text is run through a filter before publishing. Currently only Markdown is available via the L<Text::MultiMarkdown> module. 

=item *

Additionally, you can break your post into a teaser and full text by inserting the C<E<lt>!-- BREAK --E<gt>> string somewhere in the item text. The content before the break mark will be available in the C<teser> property of the C<item> object passed to your templates.

=back

=head1 CAVEATS

=over

=item *

There are no tests yet. 

=item *

The code is currently pretty messy - this is still an alpha release! 

=item *

The API is going to be changing a lot before the 1.0 release, so be sure to keep up with the development process (see L</"SUPPORT"> below) if you plann to use Miril at this stage. Things that are going to change include the structure of the configuration file, the structure of the C<item> objects, and the API for extending Miril (which has not been documented yet anyway).

=head1 SUPPORT

=head2 Website

The Miril website will be located at L<http://www.miril.org>.

=head2 Bugs and feature requests

Please use the Github issue tracker at L<http://github.com/pshangov/miril/issues> to report bugs and request features.

=head2 Mailing list

Support can be obtained via the Google Groups page: L<http://groups.google.com/group/miril>.

=head2 Repository

Miril is hosted on Github at L<http://github.com/pshangov/miril>.

=head1 AUTHOR

Peter Shangov, C<< <pshangov at yahoo.com> >>

=head1 COPYRIGHT & LICENSE

Copyright 2009 Peter Shangov.

This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

