Customize Jifty Page Layout

作者:   發佈於:  

I found myself repeating this whenever I started to put styles to my new Jifty app. Maybe it's necessary to make it easier. Actually not hard, but neither it is a trivial task.

To do this, you'll need to do these two steps:

  1. Write a MyApp::View::Page class
  2. Modify etc/config.yml to enable it

Write a MyApp::View::Page class

This class can be done by inheriting the default Jifty::View::Declare::Page class, and then override the render_page method and optionally override the render_header method. Jifty emits XHTML strict doctype by default. I started to use HTML5 these days, therefore I always override render_header method.

Here's one of my example (gist: 168919). I use a 960 grid system so I added a few class names like container_16, grid_16. That's also the reason I'm overriding the default Page class.

package MyApp::View::Page;
use strict;
use warnings;
use base qw/Jifty::View::Declare::Page/;

use Template::Declare::Tags;
use Jifty::View::Declare::Helpers;

# Let header part emits the new HTML5 prototype.
sub render_header {
    my $self = shift;
    return if $self->done_header;
    Template::Declare->new_buffer_frame;
    outs_raw("<!doctype html>\n<html>\n");
    $self->_render_header($self->_title || Jifty->config->framework('ApplicationName'));
    $self->done_header(Template::Declare->buffer->data);
    Template::Declare->end_buffer_frame;
    return '';
};

sub render_page {
    my $self = shift;

    with(id => "doc"), div {
        # render the CRUD/notify messages at the very top of the page
        # to make it really stand out.
        Jifty->web->render_messages;

        with(id=>"header"), div {
            with(class => "container_16 clearfix"), div {
                with(class => "grid_16"), div {
                    h1 { hyperlink(label => "Write", url => "/") };
                    # Should define this in MyApp::View
                    show("/menu");
                };
            };
        };

        with(class => "container_16 clearfix", id => "wrapper"), div {
            with(class => "grid_16"), div {
                # These statements are simply copied from the Jifty::View::Page
                no warnings qw( redefine once );
                local *is::title = $self->mk_title_handler();
                $self->render_pre_content_hook();
                $self->content_code->();
                $self->render_header();
                $self->render_jifty_page_detritus();
            };
        };

        with(class => "container_16 clearfix", id => "footer"), div {
            with(class => "grid_16"), div {
                outs_raw "<address>Copyright &copy; 2009 Somebody.</address>";
            };
        };
    };

    # I always put javascript at the end of the page to speed-up page-rendering.
    Jifty->web->include_javascript;

    # This method should returns coderef.
    return sub {};
}

1;

Modify etc/config.yml.

Add a key: framework.View.PageClass with value MyApp::View::Page. You should be able to find the key View near the end of the generated config.yml

framework:
    .... ( other configs)
    TemplateClass: MyApp::View
    View:
        PageClass: MyApp::View::Page

I think this is only needed when you're writing Jifty Views with Template::Declare, which is the recommended template system for Jifty these days. Not sure how does it work for mason users.