# NAME

Dancer2::Template::Caribou - Template::Caribou wrapper for Dancer2

# VERSION

version 1.0.1

# SYNOPSIS

```perl
# in 'config.yml'
template: Caribou

engines:
  template:
    Caribou:
      namespace:    MyApp::View


# and then in the application
get '/' => sub { 
    ...;

    template 'main' => \%options;
};
```

# DESCRIPTION

`Dancer2::Template::Caribou` is an interface for the [Template::Caribou](https://metacpan.org/pod/Template%3A%3ACaribou)
template system. Be forewarned, both this module and `Template::Caribou`
itself are alpha-quality software and are still subject to any changes. <Caveat
Maxima Emptor>.

## Basic Usage

At the base, if you do

```perl
get '/' => sub {
    ...

    return template 'MyView', \%options;
};
```

the template name (here _MyView_) will be concatenated with the 
configured view namespace (which defaults to _Dancer2::View_)
to generate the Caribou class name. A Caribou object is created
using `%options` as its arguments, and its inner template `page` is then
rendered. In other words, the last line of the code above becomes 
equivalent to 

```
return Dancer2::View::MyView->new( %options )->render('page');
```

## '/views' template classes

Template classes can be created straight from the `/views` directory.
Any directory containing a file named `bou` will be turned into a 
`Template::Caribou` class. Additionally, any file with a `.bou` extension
contained within that directory will be turned into a inner template for 
that class.

### The 'bou' file

The 'bou' file holds the custom bits of the Template::Caribou class.

For example, a basic welcome template could be:

```perl
# in /views/welcome/bou

use Template::Caribou::Tags::HTML ':all';

has name => ( is => 'ro' );

template page => sub {
    my $self = shift;

    html {
        head { title { 'My App' } };
        body {
            h1 { 'hello ' . $self->name .'!' };
        };
    }
};
```

which would be invoqued via

```perl
get '/hi/:name' => sub {
    template 'welcome' => { name => param('name') };
};
```

### The inner template files

All files with a '.bou' extension found in the same directory as the 'bou'
file become inner templates for the class. So, to continue with the example
above, we could change it into

```perl
# in /views/howdie/bou

use Template::Caribou::Tags::HTML ':all';

has name => ( is => 'ro' );


# in /views/howdie/page
sub {
    my $self = shift;
    html {
        head { title { 'My App' } };
        body {
            h1 { 'howdie ' . $self->name . '!' };
        };
    }
}
```

### Layouts as roles

For the layout sub-directory, an additional piece of magic is performed.
The 'bou'-marked directories are turned into roles instead of classes, which will be applied to
the template class. Again, to take our example:

```perl
# in /views/layouts/main/bou
# empty file

# in /views/layouts/main/page

# the import of tags really needs to be here 
# instead than in the 'bou' file 
use Template::Caribou::Tags::HTML ':all';

html {
    head { title { 'My App' } };
    body {
        show( 'inner' );
    };
}

# in /views/hullo/bou

use Template::Caribou::Tags::HTML ':all';

has name => ( is => 'ro' );

# in /views/howdie/inner
h1 { 'hullo ' . $self->name . '!' };
```

# CONFIGURATION

- namespace 

    The namespace under which the Caribou classes are created.
    defaults to `Dancer2::View`.

# CONVENIENCE ATTRIBUTES AND METHODS

Auto-generated templates have the
[Dancer2::Template::Caribou::DancerVariables](https://metacpan.org/pod/Dancer2%3A%3ATemplate%3A%3ACaribou%3A%3ADancerVariables) role automatically applied to
them, which give them helper methods like `uri_for()` and `context()` to
interact with the Dancer environment. If you roll out your own template
classes, you simply have to apply the role to have access to the same niftiness.

```perl
package Dancer2::View::MyView;

use Template::Caribou;

with qw/ 
    Dancer2::Template::Caribou::DancerVariables 
/;

template page => sub {
    my $self = shift;
    
    print ::RAW $self->uri_for( '/foo' );
};
```

- context()

    The [Dancer2::Core::Context](https://metacpan.org/pod/Dancer2%3A%3ACore%3A%3AContext) object associated with the current request.

# AUTHOR

Yanick Champoux <yanick@babyl.dyndns.org> [![endorse](http://api.coderwall.com/yanick/endorsecount.png)](http://coderwall.com/yanick)

# COPYRIGHT AND LICENSE

This software is copyright (c) 2023 by Yanick Champoux.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
