NAME

Catalyst::View::Markdown - Markdown View Class

SYNOPSIS

# use the helper to create your View

    myapp_create.pl view MD Markdown

# add custom configration in View/MD.pm

    __PACKAGE__->config(
        # any Markdown configuration items go here
        FILENAME_EXTENSION => '.md',
        empty_element_suffix => '/>',
        tab_width => 4,
        trust_list_start_value => 1,
    );

# add include path configuration in MyApp.pm

    __PACKAGE__->config(
        'View::MD' => {
            INCLUDE_PATH => [
                __PACKAGE__->path_to( 'root', 'src' ),
                __PACKAGE__->path_to( 'root', 'lib' ),
            ],
        },
    );

# render view from lib/MyApp.pm or lib/MyApp::Controller::SomeController.pm

    sub message : Global {
        my ( $self, $c ) = @_;
        $c->stash->{markdown_filename} = 'message';
        $c->forward( $c->view('MD') );
    }

DESCRIPTION

This is the Catalyst view class for Markdown. Your application should define a view class which is a subclass of this module. Throughout this manual it will be assumed that your application is named MyApp and you are creating a Markdown view named MD; these names are placeholders and should always be replaced with whatever name you've chosen for your application and your view. The easiest way to create a Markdown view class is through the myapp_create.pl script that is created along with the application:

    $ script/myapp_create.pl view MD Markdown

This creates a MyApp::View::MD.pm module in the lib directory (again, replacing MyApp with the name of your application) which looks something like this:

    package FooBar::View::MD;
    use Moose;

    extends 'Catalyst::View::Markdown';

    __PACKAGE__->config(DEBUG => 'all');

Now you can modify your action handlers in the main application and/or controllers to forward to your view class. You might choose to do this in the end() method, for example, to automatically forward all actions to the Markdown view class.

    # In MyApp or MyApp::Controller::SomeController

    sub end : Private {
        my( $self, $c ) = @_;
        $c->forward( $c->view('MD') );
    }

But if you are using the standard auto-generated end action, you don't even need to do this!

    # in MyApp::Controller::Root
    sub end : ActionClass('RenderView') {} # no need to change this line

    # in MyApp.pm
    __PACKAGE__->config(
        ...
        default_view => 'MD',
    );

This will Just Work. And it has the advantages that:

  • If you want to use a different view for a given request, just set << $c->stash->{current_view} >>. (See Catalyst's $c->view method for details.

  • << $c->res->redirect >> is handled by default. If you just forward to View::MD in your end routine, you could break this by sending additional content.

See Catalyst::Action::RenderView for more details.

CONFIGURATION

There are a three different ways to configure your view class. The first way is to call the config() method in the view subclass. This happens when the module is first loaded.

    package MyApp::View::MD;
    use Moose;
    extends 'Catalyst::View::Markdown';

    __PACKAGE__->config({
        tab_width => 4,
    });

You may also override the configuration provided in the view class by adding a 'View::MD' section to your application config.

This should generally be used to inject the include paths into the view to avoid the view trying to load the application to resolve paths.

    .. inside MyApp.pm ..
    __PACKAGE__->config(
        'View::MD' => {
            INCLUDE_PATH => [
                __PACKAGE__->path_to( 'root', 'markdown', 'lib' ),
                __PACKAGE__->path_to( 'root', 'markdown', 'src' ),
            ],
        },
    );

You can also configure your view from within your config file if you're using Catalyst::Plugin::ConfigLoader. This should be reserved for deployment-specific concerns. For example:

    # MyApp_local.conf (Config::General format)

    <View MD>
      INCLUDE_PATH __path_to('root/markdown/custom_site')__
      INCLUDE_PATH __path_to('root/markdown')__
    </View>

might be used as part of a simple way to deploy different instances of the same application with different themes.

DYNAMIC INCLUDE_PATH

Sometimes it is desirable to modify INCLUDE_PATH for your templates at run time.

If you need to add paths to the end of INCLUDE_PATH, there is an include_path() accessor available:

    push( @{ $c->view('MD')->include_path }, qw/path/ );

Note that if you use include_path() to add extra paths to INCLUDE_PATH, you MUST check for duplicate paths. Without such checking, the above code will add "path" to INCLUDE_PATH at every request, causing a memory leak.

A safer approach is to use include_path() to overwrite the array of paths rather than adding to it. This eliminates both the need to perform duplicate checking and the chance of a memory leak:

    @{ $c->view('MD')->include_path } = qw/path another_path/;

RENDERING VIEWS

The view plugin renders the template specified in the markdown_filename item in the stash.

    sub message : Global {
        my ( $self, $c ) = @_;
        $c->stash->{markdown_filename} = 'message.md';
        $c->forward( $c->view('MD') );
    }

If a stash item isn't defined, then it instead uses the stringification of the action dispatched to (as defined by $c->action) in the above example, this would be message, but because the default is to append '.md', it would load root/message.md.

The output generated by the file is stored in $c->response->body.

CAPTURING FILE OUTPUT

If you wish to use the output of a Markdown file for some other purpose than displaying in the response, e.g. for sending an email, this is possible using Catalyst::Plugin::Email and the render method:

  sub send_email : Local {
    my ($self, $c) = @_;

    $c->email(
      header => [
        To      => 'me@localhost',
        Subject => 'A Markdown Email',
      ],
      body => $c->view('MD')->render($c, 'email.md'),
    );
  # Redirect or display a message
  }

METHODS

new

The constructor for the Markdown view. Sets up the Markdown provider, and reads the application config.

process($c)

Renders the template specified in $c->stash->{markdown_filename} or $c->action (the private name of the matched action). Calls render to perform actual rendering. Output is stored in $c->response->body.

It is possible to forward to the process method of a Markdown view from inside Catalyst like this:

    $c->forward('View::MD');

N.B. This is usually done automatically by Catalyst::Action::RenderView.

render($c, $md_filename)

Renders the given file and returns output. Throws a Template::Exception object upon error.

If $md_filename is a scalar reference, the value will be use as Markdown text instead of searching for a file - this allows Markdown to be easily stored in other systems, e.g. a database table.

To use the render method outside of your Catalyst app, just pass a undef context. This can be useful for tests, for instance.

config

This method allows your view subclass to pass additional settings to the Markdown configuration hash, or to set the options as below:

INCLUDE_PATH

The list of paths Markdown will look for files in. The first matching file will be used.

CLASS

Allows you to specify a custom class to use as the template class instead of Text::Markdown.

    package MyApp::View::MD;
    use Moose;
    extends 'Catalyst::View::Markdown';

    use Text::MultiMarkdown;

    __PACKAGE__->config({
        CLASS => 'Text::MultiMarkdown',
    });

This is useful if you want to use your own subclasses of Markdown.

HELPERS

The Catalyst::Helper::View::Markdown helper module is provided to create your view module. There are invoked by the myapp_create.pl script:

    $ script/myapp_create.pl view Web Markdown

The Catalyst::Helper::View::Markdown module creates a basic Markdown view module.

SEE ALSO

Catalyst, Catalyst::Helper::View::Markdown, Template::Manual

AUTHORS

Richard Wallman, wallmari@bossolutions.co.uk

COPYRIGHT

This program is free software. You can redistribute it and/or modify it under the same terms as Perl itself.